question

MHMukit-7272 avatar image
0 Votes"
MHMukit-7272 asked surferonwww answered

How to add custom claims on user identity .net 6

When logging in, I was looking for a way to add more user claims. I discovered the following implementation on the.net 6 using IUserClaimsPrincipalFactory. However, this has the drawback of calling the database with each HTTP request. So instead of calling the database with every http request, I simply wanted to do so once (during initial authentication).

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.iclaimstransformation?view=aspnetcore-6.0

I found the following implmentation for .net 5.
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/add-user-data?view=aspnetcore-5.0&tabs=visual-studio#add-claims-to-identity-using-iuserclaimsprincipalfactoryapplicationuser

Please explain to me why the IUserClaimsPrincipalFactory is not listed in the.net 6 documentation. What are the drawbacks, and is there another option than utilizing/not utilizing IClaimsTransformation to call the database once during authentication not for each HTTP call?




dotnet-aspnet-core-mvc
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Please explain to me why the IUserClaimsPrincipalFactory is not listed in the.net 6 documentation.

I don't know why the document does not include the description of IUserClaimsPrincipalFactory but it can be used in the .NET 6.0 app.

0 Votes 0 ·

Hi @MHMukit-7272 ,

Please explain to me why the IUserClaimsPrincipalFactory is not listed in the.net 6 documentation.

Refer to:Note :

This section isn't an extension of the previous tutorial. To apply the following steps to the app built using the tutorial, see this GitHub issue.


Besides, from this we see

Add claims to Identity using IUserClaimsPrincipalFactory was dropped from the 6.0 version of the tutorial because it doesn't belong to that doc

0 Votes 0 ·

Hi @QingGuo-MSFT

I understand why the document was removed from that section. But I was unable to locate t he section titled "Add claims to Identity using IUserClaimsPrincipalFactory" in the entire.net 6 document. Is there a reason why.net 6 does not recommend this procedure?

My primary concern is actually "how to add new claims to identity without accessing the database on every HTTP request" (as IClaimsTransformation interface is called on each HTTP request if I use any database call then the db will also be called on each request). I simply want to add the claims on user login, so that they function similarly to other default claims, which only fetch relevant information at first authentication and store it on cokies.

0 Votes 0 ·

@MHMukit-7272 ,

But I was unable to locate t he section titled "Add claims to Identity using IUserClaimsPrincipalFactory" in the entire.net 6 document.

Have a look at Link for "Add claims to Identity using IUserClaimsPrincipalFactory" doesn't lead to anywhere useful

"how to add new claims to identity without accessing the database on every HTTP request"

What do you mean ? Do you want to add a new identity claim without hitting the database for every HTTP request?

I simply want to add the claims on user login, so that they function similarly to other default claims, which only fetch relevant information at first authentication and store it on cokies.

If claims are not persisted in the database, but added to a cookie directly then will not be automatically re-added next time the user is logged-in.



0 Votes 0 ·
Show more comments

Please follow the link below and image
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-5.0
241835-image.png


For .net 5 the sention for "IUserClaimsPrincipalFactory" was there on page "Mapping, customizing, and transforming claims in ASP.NET Core"

But for .net 6
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0
241757-image.png

No such section






0 Votes 0 ·
image.png (116.2 KiB)
image.png (139.2 KiB)
QingGuo-MSFT avatar image
0 Votes"
QingGuo-MSFT answered

Hi @MHMukit-7272 ,

So instead of calling the database with every http request, I simply wanted to do so once (during initial authentication).

Try to add claims in an ASP.NET Core middleware after Authentication.

Middleware:

  public class SomeMiddleware
     {
         private readonly RequestDelegate _next;
    
         public SomeMiddleware(RequestDelegate next)
         {
             _next = next;
         }
    
         public async Task InvokeAsync(HttpContext httpContext)
         {
             if (httpContext.User != null && httpContext.User.Identity.IsAuthenticated)
             {
                 var claims = new List<Claim>
             {
                 new Claim("SomeClaim", "SomeValue")
             };
    
                 var appIdentity = new ClaimsIdentity(claims);
                 httpContext.User.AddIdentity(appIdentity);
             }
    
             await _next(httpContext);
         }


Program:


   app.UseAuthentication();
      app.UseAuthorization();
      app.UseMiddleware<SomeMiddleware>();



If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Qing Guo

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

which identity provider are you using?

1) if custom provider, you add the claim to the entity database and map:

https://learn.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0

2) if using oauth, then use the OnTokenValidated event to add the claim. it will get copied to the cookie.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.jwtbearer.jwtbearerevents.ontokenvalidated?view=aspnetcore-6.0

note: if you are using azure ad access tokens, they will need to added on every request. I use a cache instead of a database.





5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

surferonwww avatar image
0 Votes"
surferonwww answered

However, this has the drawback of calling the database with each HTTP request. So instead of calling the database with every http request, I simply wanted to do so once (during initial authentication).

You can do so by using the IUserClaimsPrincipalFactory.

For example, how to add the Phone number to ClaimsIdentity is described below.

244442-account.jpg


(1) Add the following class as the service:

 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Options;
 using MvcCore6App2.Data;
 using System.Security.Claims;
    
 namespace MvcCore6App2.Services
 {
     public class CustomClaimsPrincipalFactory :
         UserClaimsPrincipalFactory<ApplicationUser>
     {
         public CustomClaimsPrincipalFactory(
             UserManager<ApplicationUser> userManager,
             IOptions<IdentityOptions> optionsAccessor)
                 : base(userManager, optionsAccessor)
         {
         }
    
         // This method is called only when login. It means that "the drawback 
         // of calling the database with each HTTP request" never happen.
         public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
         {
             var principal = await base.CreateAsync(user);
                
             if (!string.IsNullOrEmpty(user.PhoneNumber))
             {
                 if (principal.Identity != null)
                 {
                     ((ClaimsIdentity)principal.Identity).AddClaims(
                         new[] {  new Claim("Phone", user.PhoneNumber) });
                 }
             }
    
             return principal;
         }
     }
 }


(2) Register the above service in the Program.cs as follows:

 builder.Services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, 
     CustomClaimsPrincipalFactory>();

(3) Result after login:

244426-debug.jpg



account.jpg (38.8 KiB)
debug.jpg (147.9 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.