Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Authentication Cookie Not Being Retrieved

I am having a hard time implementing "Remember Me" functionality in an MVC application with a custom principal. I have boiled it down to ASP.NET not retrieving the authentication cookie for me. I have included a snapshot below from Google Chrome.

  1. Shows the results of Request.Cookies that is set within the controller action and placed in ViewData for the view to read. Notice that it is missing the .ASPXAUTH cookie

  2. Shows the results from the Chrome developer tools. You can see that .ASPXAUTH is included here.

alt text

What may be the issue here? Why does ASP.NET not read this value from the cookie collection?

My application uses a custom IPrincipal. BusinessPrincipalBase is a CSLA object that ust implements IPrincipal. Here is the code for that:

[Serializable()]
public class MoralePrincipal : BusinessPrincipalBase
{
    private User _user;

    public User User
    {
        get
        {
            return _user;
        }
    }

    private MoralePrincipal(IIdentity identity) : base(identity)
    {
        if (identity is User)
        {
            _user = (User)identity;
        }
    }

    public override bool Equals(object obj)
    {
        MoralePrincipal principal = obj as MoralePrincipal;
        if (principal != null)
        {
            if (principal.Identity is User && this.Identity is User)
            {
                return ((User)principal.Identity).Equals(((User)this.Identity));
            }
        }
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public static bool Login(string username, string password)
    {
        User identity = User.Fetch(username, password);
        if (identity == null || !identity.IsAuthenticated)
        {
            identity = (User)User.UnauthenicatedIdentity;
        }

        MoralePrincipal principal = new MoralePrincipal(identity);
        Csla.ApplicationContext.User = principal;
        Context.Current.User = identity;

        return identity != null && identity.IsAuthenticated;
    }

    public static void Logout()
    {
        IIdentity identity = User.UnauthenicatedIdentity;
        MoralePrincipal principal = new MoralePrincipal(identity);
        ApplicationContext.User = principal;
        Context.Current.User = identity as User;
    }

    public override bool IsInRole(string role)
    {
        if (Context.Current.User == null || Context.Current.Project == null)
        {
            return false;
        }

        string userRole = Context.Current.User.GetRole(Context.Current.Project.Id);
        return string.Compare(role, userRole, true) == 0;
    }

The application also uses a custom membership provider. Here is the code for that.

public class MoraleMembershipProvider : MembershipProvider
{
    public override bool ValidateUser(string username, string password)
    {
        bool result = MoralePrincipal.Login(username, password);
        HttpContext.Current.Session["CslaPrincipal"] = ApplicationContext.User;
        return result;
    }

    #region Non-Implemented Properties/Methods

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

    // Everything else just throws a NotImplementedException

    #endregion
}

I do not think that any of this is related because the bottom line is that the Request.Cookies does not return the authentication cookie. Is it related to the size of the cookie? I heard there are issues to the size of the cookie.

UPDATE: It seems that the issue revolves around subdomains. This site was being hosted with a subdomain and the cookie domain was left blank. Does anyone have any pointers on how I can get the auth cookie to work with all domains (e.g. http://example.com, http://www.example.com, and http://sub.example.com)?

like image 334
Jamie Wright Avatar asked Jun 07 '10 11:06

Jamie Wright


2 Answers

If you are trying to store the actual User object in the cookie itself, it is probably too big to store as a cookie. I am not too familiar with the MVC authentication stuff, but in web forms I generally do the following:

FormsAuthentication.RedirectFromLoginPage(user_unique_id_here, false);

The second parameter is for the persistency you are looking for.

From there I create a custom context (UserContext) that I populate via HttpModule that gives me access to all the user and role information.

Since I do not develop in MVC (yet) or CSLA, I'm not sure how much more help I can be. If I were you, I would also ditch the custom membership provider. You might as well just call MoralePrincipal.Login directly in your Authentication controller.

like image 113
sestocker Avatar answered Nov 15 '22 06:11

sestocker


The rememberMe stuff should be set by the FormsAuthenticationService (in MVC2) or the FormsAuthentication static class in MVC1, if you're using the 'regular' AccountController's code. If you changed that code, did you remember to add in the (optional) boolean param indicating whether to use a persistent cookie or not?

It sounds to me like you're getting a session cookie, but not a persistent cookie.

like image 32
Paul Avatar answered Nov 15 '22 04:11

Paul