Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
135 views
in Technique[技术] by (71.8m points)

How can I add/update a claim in .NET Core 3.1 after I've already authenticated?

In my scenario, I have a many-to-many relationship between users and businesses. So, a business can have many employees, and a user can be an employee to many businesses.

On the login page, I only want to show email & password textboxes. Once they authenticate successfully, I'd like to redirect them to a page that has a dropdown of the businesses they're employed with.

Since they have already authenticated, their claims have already been populated. How do I add another claim (their BusinessID) afterwards?

question from:https://stackoverflow.com/questions/65885452/how-can-i-add-update-a-claim-in-net-core-3-1-after-ive-already-authenticated

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer from refers when to you authenticate and get the claims from an OAUTH server. We don't know if you are using local identity tables, or OAUTH, but in any case.

  1. Define your own UserClaimsPrincipalFactory class implementation
  2. Register as a services in startup ConfigureServices
  3. Invoke the GenerateClaimsAsync method when the user select the Business type.

I include some old code (finally we implemented in another way), but maybe can help you.

  1. Define you own UserClaimsPrincipalFactory. For this, I have customized the User class, and add a new factory
    using System;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Security.Claims;
    using System.Text.Json.Serialization;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.Extensions.Options;
    
    namespace Common.Models.Identity {
        public class User : IdentityUser<int> {
    
    
            public bool SendAlertByEmail { get; set; }
            public int ClientId { get; set; } = Client.DefaultClientId;
            [JsonIgnore, ForeignKey("ClientId")]
            public virtual Client Client { get; set; } = null!;
        }
    
        public class ApplicationUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<User> {
            public ApplicationUserClaimsPrincipalFactory(
                            UserManager<User> userManager,
                            IOptions<IdentityOptions> optionsAccessor)
                            : base(userManager, optionsAccessor) {
            }
    
            protected override async Task<ClaimsIdentity> GenerateClaimsAsync(User user) {
                ClaimsIdentity identity;
    
                identity = await base.GenerateClaimsAsync(user);
                identity.AddClaim(new Claim("ClientId", user.ClientId.ToString()));
                identity.AddClaim(new Claim("ClientDescription", user.Client.Description));
                return identity;
            }
        }
    }
  1. In your ConfigureServices, configure this

     #region Configure identity
     services
         .AddDefaultIdentity<User>(
             options => {
                 options.SignIn.RequireConfirmedAccount = true;
                 options.Stores.MaxLengthForKeys = 256;            // Max length for key. Regenerate migration if change this
             })
         .AddEntityFrameworkStores<ApplicationDbContext>()
         .AddDefaultUI()
         .AddDefaultTokenProviders()
         .AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>();
    
     services.Configure<IdentityOptions>(options => {
         // Password settings.
         options.Password.RequireDigit = true;
         options.Password.RequireLowercase = true;
         options.Password.RequireNonAlphanumeric = true;
         options.Password.RequireUppercase = true;
         options.Password.RequiredLength = 6;
         options.Password.RequiredUniqueChars = 1;
    
         // Lockout settings.
         options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
         options.Lockout.MaxFailedAccessAttempts = 5;
         options.Lockout.AllowedForNewUsers = true;
    
         // User settings.
         options.User.AllowedUserNameCharacters =
         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
         options.User.RequireUniqueEmail = false;
     });
    
     services.ConfigureApplicationCookie(options => {
         // Cookie settings
         options.Cookie.HttpOnly = true;
         options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    
         options.LoginPath = "/Identity/Account/Login";
         options.AccessDeniedPath = "/Identity/Account/AccessDenied";
         options.SlidingExpiration = true;
     });
     #endregion Configure identity
    
  2. Use IoC to pass your ApplicationUserClaimsPrincipalFactory to your "Select business/client" request, and use it for add the claim


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...