MVC Identity 2 using FormsAuthenticationTicket

后端 未结 2 630
感情败类
感情败类 2020-12-21 13:50

I am replacing the (HttpContext.Current.User) IPrincipal with a custom version so I can store more information login and the user. I have done this before using the FormsAu

相关标签:
2条回答
  • 2020-12-21 14:09

    There are Claims that serve exactly the same purpose. Only new API is actually purposed this way.

    Claims are a basically a Dictionary<String, String> that is stored in auth-cookie and available through IPrincipal. But you don't need to do ICustomPrincipal because actual object that you get behind IPrincipal is ClaimsPrincipal and that has a list of claims.

    You'd add extra information to Idnentity object just before the login:

    public async override Task CreateIdentityAsync(ApplicationUser applicationUser)
    {
        var identity = await base.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);
    
        identity.AddClaim(new Claim("MyApp:FullName", applicationUser.FullName));
        return identity;
    }
    

    And then you'd be able to get this data out from IPrincipal via extension:

    public static String GetFullName(this IPrincipal principal)
    {
        var claimsPrincipal = principal as ClaimsPrincipal;
        if (claimsPrincipal == null)
        {
             throw new Exception("User is not logged in!");
        }
        var nameClaim = principal.Claims.FirstOrDefault(c => c.Type == "MyApp:FullName");
        if (nameClaim != null)
        {
            return nameClaim.Value;
        }
    
        return String.Empty;
    }
    

    I have used this method successfully in a few projects already. See other similar answers for more code samples.
    Here is another article, though I discourage from using Thread.CurrentPrincipal or ClaimsPrincipal.Current in MVC application - you don't always get what you expect, especially when user is not logged in or on early stages of AppPool start up.

    0 讨论(0)
  • 2020-12-21 14:23

    This approach works for me (Using MVC4), slightly different from above.

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            userIdentity.AddClaim(new Claim("MyApp:OrganizationId", OrganizationID.ToString()));
    
            return userIdentity;
        }
    
        public int OrganizationID { get; set; }
    }
    

    Extension method. Note you should use claimsPrincipal variable (instead of principal variable) to obtain the claims. I think that's a little mistake in the excelent answer of @trailmax (sorry for not comment this in your answer, my reputation doesn't allow me). Also, I use IIdentity instead of IPrincipal

    public static class IdentityExtensions
        {
            public static int GetOrganizationId(this IIdentity principal)
            {
                var claimsPrincipal = principal as ClaimsIdentity;
                if (claimsPrincipal == null)
                {
                    throw new Exception("User is not logged in!");
                }
    
                var nameClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "MyApp:OrganizationId");
                if (nameClaim != null)
                {
                    return int.Parse(nameClaim.Value);
                }
    
                throw new Exception("ID doesn't exists");
            }
        }
    

    And then, I use the extension method in the controller like this:

    var organizationId = User.Identity.GetOrganizationId();
    

    Hope this is useful to someone.

    0 讨论(0)
提交回复
热议问题