Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 2 - Membership Provider - ValidateUser() - return login error message

How do I return a string message from the ValidateUser method in my custom membership provider? I need this because I want to perform several checks (user is approved, user is blocked etc.) and give the user a good description, if the login process fails.

One option would be to throw an exception, but someone said that this is not a proper way for handling such situations.

For now I can only say "Login failed" or "Login succeeded" because of the bool return type.

Is it possible to create my own ValidateUser method or does the ASP.NET Membership mechanism uses the default one in it's internal operations?

like image 496
Cosmo Avatar asked Mar 03 '10 16:03

Cosmo


2 Answers

Those are two different operations.

To see if a user is approved, locked out, etc., look up the user (with GetUser()) and look at the IsApproved, IsLockedOut, etc. properties of the returned user. ValidateUser() is only for login, but you can do both.

like image 156
Craig Stuntz Avatar answered Sep 29 '22 01:09

Craig Stuntz


You can implement any methods you want to on your custom provider, and in your case it might make sense to do so and just cast Membership to your type before using.

But breaking the interface to get some simple out of band info may come back to bite you in the future. There are other ways to do this and preserve the provider api and keep your future options open.

In the past, I have used a cookie to pass out-of-band info like this from a provider to the consumer.

The HttpContext.Current is the same for the provider as it is for the page so a cookie set in the provider can be read in the consumer.

Just make sure that you remove the cookie after calling your provider. Creating a transient cookie helps minimize mistakes, but just remove it from the collection anyway.

Here is a working example.

CookieChannelMembershipProvider

using System;
using System.Web;
using System.Web.Security;

namespace CookieChannel
{
    public class CookieChannelMembershipProvider : MembershipProvider
    {
        public override bool ValidateUser(string username, string password)
        {
            if(username=="asshat")
            {
                HttpContext.Current.Request.Cookies.Add(new HttpCookie("__cookiechannel", "user is an asshat. do not let him in."));
                return false;
            }
            return true;
        }

        #region Not implemented

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override string ApplicationName
        {
            get { throw new NotImplementedException(); }
            set { throw new NotImplementedException(); }
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }


        public override MembershipUser CreateUser(string username, string password, string email,
                                                  string passwordQuestion, string passwordAnswer, bool isApproved,
                                                  object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password,
                                                             string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }


        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
                                                                 out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
                                                                  out int totalRecords)
        {
            throw new NotImplementedException();
        } 
        #endregion
    }
}

Web.config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
    <authentication mode="Windows" />
    <membership defaultProvider="cookieChannelProvider" userIsOnlineTimeWindow="15">
      <providers>
        <add
          name="cookieChannelProvider"
          type="CookieChannel.CookieChannelMembershipProvider, CookieChannel"
          connectionStringName="none"
          enablePasswordRetrieval="true"
          enablePasswordReset="true"
          requiresQuestionAndAnswer="true"
          />
      </providers>
    </membership>
  </system.web>
</configuration>

Default.aspx

<%@ Page Language="C#" %>
<script runat="server">
    protected void Button1_Click(object sender, EventArgs e)
    {
        ValidateUser("user", "user");
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        ValidateUser("asshat", "asshat");
    }

    private void ValidateUser(string username, string password)
    {
        bool validated = Membership.ValidateUser(username, password);
        string message = validated.ToString();

        if (Request.Cookies["__cookiechannel"] != null)
        {
            message += ":" + Request.Cookies["__cookiechannel"].Value;
            Request.Cookies.Remove("__cookiechannel");
        }
        Label1.Text = message;
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
            Text="Validate Valued User" />
        <asp:Button ID="Button2" runat="server" onclick="Button2_Click" 
            Text="Validate Asshat User" />

    </div>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    </form>
</body>
</html>
like image 35
Sky Sanders Avatar answered Sep 29 '22 01:09

Sky Sanders