locked
Help Needed in Claims RRS feed

  • Question

  • User1489758560 posted

    Hi,

    I would like to add custom claims in the login page. so that i wanted to use across the applications. i tried to google it and found a way to use the claims factory the code is below,

    public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
        {
            public MyUserClaimsPrincipalFactory(
               UserManager<ApplicationUser> userManager,
               IOptions<IdentityOptions> optionsAccessor)
               : base(userManager, optionsAccessor)
            {
            }
    
            protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
            {
                var identity = await base.GenerateClaimsAsync(user);
                identity.AddClaim(new Claim("MemberID", user.MemberID.ToString()));
                identity.AddClaim(new Claim("UserName", user.UserName));
                identity.AddClaim(new Claim("PrimaryEmail", user.PrimaryEmail));
                identity.AddClaim(new Claim("ApplicationPin", user.ApplicationPin));
                identity.AddClaim(new Claim("FirstName", user.FirstName));
                identity.AddClaim(new Claim("LastName", user.LastName));
                return identity;
            }
        }
    
    
    public class ApplicationUser : IdentityUser
        {
            public int MemberID{ get; set; }
            public new string UserName { get; set; }
            public new string PrimaryEmail { get; set; } 
            public string ApplicationPin { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }

    Register in startup cs:

    services.AddDefaultIdentity<ApplicationUser>()
                    .AddClaimsPrincipalFactory<MyUserClaimsPrincipalFactory>();
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    in the login model, after validated the username and password, i want to add the the users custom data to the claims. so that i can use those across the application. 

    var result = await ApplicationBiz.VerifyApplication(string UserName,string Password)
    
    if(result.IsValid)
    {
      // i want to add the values of results to claims.
    
    result.MemberID
    result.UserName
    result.PrimaryEmail
    result.ApplicationPin
    result.FirstName
    result.LastName
    	
    
    }
    
    // struggling How to add it to the custom claims here ?????????
    
      var principal = new ClaimsPrincipal(identity);
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
                    return RedirectToPage("~/AppSecurity/Home");

    Please help me on this requirement  wish some code will be highly appreciated. 

    Sunday, February 9, 2020 1:45 PM

Answers

  • User475983607 posted

    the above is the code  i made it in configuration services. so after the session 30 mins, if there is no action on then application, will it take care of clearing the claims and cookie and redirect to login? am asking about session timeout here . please share the knowledge.

    You've configure the authentication cookie and token.  Session is a different framework feature.   Browser's do not send expired cookies to the server so the token cached within the cookie is not sent and therefore the request is not authenticated. 

    Since you are interested in the subject, you should go through the links provided above and perhaps do a little research on cookies.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 9, 2020 6:18 PM

All replies

  • User475983607 posted

    Just add the claims to the principal.  The official authentication cookie documentation has a code example that illustrates how to do this...

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1

    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, user.Email),
        new Claim("FullName", user.FullName),
        new Claim(ClaimTypes.Role, "Administrator"),
    };
    
    var claimsIdentity = new ClaimsIdentity(
        claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
    var authProperties = new AuthenticationProperties
    {
        //AllowRefresh = <bool>,
        // Refreshing the authentication session should be allowed.
    
        //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
        // The time at which the authentication ticket expires. A 
        // value set here overrides the ExpireTimeSpan option of 
        // CookieAuthenticationOptions set with AddCookie.
    
        //IsPersistent = true,
        // Whether the authentication session is persisted across 
        // multiple requests. When used with cookies, controls
        // whether the cookie's lifetime is absolute (matching the
        // lifetime of the authentication ticket) or session-based.
    
        //IssuedUtc = <DateTimeOffset>,
        // The time at which the authentication ticket was issued.
    
        //RedirectUri = <string>
        // The full path or absolute URI to be used as an http 
        // redirect response value.
    };
    
    await HttpContext.SignInAsync(
        CookieAuthenticationDefaults.AuthenticationScheme, 
        new ClaimsPrincipal(claimsIdentity), 
        authProperties);

    Keep in mind that if you are using Identity, then the claims located in the UserClaim table are simply included. 

    Sunday, February 9, 2020 1:59 PM
  • User1489758560 posted

    Hi,

    thank you for your reply and on your sample

    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, user.Email),
        new Claim("FullName", user.FullName),
        new Claim(ClaimTypes.Role, "Administrator"),
    };

    this is default claim type. but i wanted to add the custom claim which is not in the default claimType. from my database after validation, i am getting couple of fields like MemberId,UserName,PrimaryEmail,ApplicationPin,FirstName,LastName. 

    i referred the below url 

    https://korzh.com/blogs/dotnet-stories/add-extra-user-claims-aspnet-core-webapp

    But , i am struggling how to add my custom fields in the claims before 

    await HttpContext.SignInAsync.

    Any help please.

    Sunday, February 9, 2020 3:11 PM
  • User475983607 posted

    You misunderstand the fundamentals.  The claim type is just a string constant.  You can add whatever claim type, which is just a string, you like.  If you wish, you can use a static class with constants so you get intelliscence.

    public static class CustomClaimTypes
    {
    	public const string Name = "name";
    	public const string Email = "email";
    	public const string DefaultRole = "role";
    }

    Oh, and use the standard UserManage to add user claims.  This should e done as part of the account creation process.  

    Sunday, February 9, 2020 5:00 PM
  • User1489758560 posted

    thank you for the reply and i have added the claim and created the extensions to get it from intellisense. i am able to get the claim in other pages using the extensions which is fine now. just another question related to this,. 

    await HttpContext.SignOutAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme);
                return RedirectToPage("/Login");

    this is the sign out code and will this takes care of clearing  the authentication cookie and any claims attached to the identity?

    services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
                services.AddAuthentication(options =>
                {
                    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    
                }).AddCookie(options => 
                {
                    options.LoginPath = "/Login";
                    options.AccessDeniedPath = "/AccessDenied";
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                    options.SlidingExpiration = true;
                }
                );
                services.AddMvc().AddRazorPagesOptions(options =>
                {
                    options.Conventions.AuthorizeFolder("/");
                    options.Conventions.AllowAnonymousToPage("/Login");
                });

    the above is the code  i made it in configuration services. so after the session 30 mins, if there is no action on then application, will it take care of clearing the claims and cookie and redirect to login? am asking about session timeout here . please share the knowledge.

    Sunday, February 9, 2020 6:08 PM
  • User475983607 posted

    the above is the code  i made it in configuration services. so after the session 30 mins, if there is no action on then application, will it take care of clearing the claims and cookie and redirect to login? am asking about session timeout here . please share the knowledge.

    You've configure the authentication cookie and token.  Session is a different framework feature.   Browser's do not send expired cookies to the server so the token cached within the cookie is not sent and therefore the request is not authenticated. 

    Since you are interested in the subject, you should go through the links provided above and perhaps do a little research on cookies.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 9, 2020 6:18 PM
  • User1489758560 posted

    thank you and it helped me to understand. appreciated.

    Monday, February 17, 2020 5:39 PM