【问题标题】:Authentication handler in .NET Core 2.2 can not access claims which were set by another authentication handler.NET Core 2.2 中的身份验证处理程序无法访问由另一个身份验证处理程序设置的声明
【发布时间】:2019-07-02 13:57:35
【问题描述】:

我有自定义身份验证处理程序 (AuthenticationHandler<TOptions>),它从自定义 cookie 进行身份验证。此 cookie 包含用户 ID 和其他用户信息。所以这个处理程序使用一些逻辑进行一些解密,以解析 cookie 并提取所有数据。

然后我有另一个身份验证处理程序,它应该获取所有用户角色。并且这个处理程序需要用户 ID,这是由第一个处理程序设置的。但是,当我尝试访问声明时,没有。

protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
    var allClaims = this.Context.User.Claims;
    var userId =    allClaims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
    var identity =  this.Context.User.Identities.FirstOrDefault();
    var claims2 = identity.claims;
    var userId2 =   identity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
}

allClaims 计数为 0userIdnullidentity 来自第一个身份验证处理程序,它不是 null。但是claims2 计数是0

稍后我可以在控制器中查看所有声明。

我可以从第一个处理程序中复制解密逻辑,但感觉不对。

那么在此身份验证过程中,我如何访问来自其他处理程序的声明?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc claims-based-identity


    【解决方案1】:

    在第一个 AuthenticationHandler 中,您应该构建声明,将它们放入 AuthenticationTicket 并返回:

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
    
        var claims = new[] { new Claim(ClaimTypes.Name, "nanyu") };
        var identity = new ClaimsIdentity(claims, Scheme.Name);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);
        return AuthenticateResult.Success(ticket);
    }
    

    您可以编写一个自定义中间件,手动调用 AuthenticateAsync() 并创建一个包含您需要的所有身份的 ClaimsPrincipal :

    app.UseAuthentication();
    app.Use(async (context, next) =>
    {
        var principal = new ClaimsPrincipal();
    
        var result1 = await context.AuthenticateAsync("MyScheme");
        if (result1?.Principal != null)
        {
            principal.AddIdentities(result1.Principal.Identities);
        }
    
        var result2 = await context.AuthenticateAsync("MyScheme2");
        if (result2?.Principal != null)
        {
            principal.AddIdentities(result2.Principal.Identities);
        }
    
        context.User = principal;
    
        await next();
    });
    

    配置身份验证:

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "MyScheme";
        options.DefaultChallengeScheme = "MyScheme";
    })
    .AddCustomAuth(o => { }).AddCustomAuthTwo(o => { });
    

    CustomAuthExtensions.cs:

    public static class CustomAuthExtensions
    {
        public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
        {
            return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("MyScheme", "MyAuth", configureOptions);
        }
        public static AuthenticationBuilder AddCustomAuthTwo(this AuthenticationBuilder builder, Action<CustomAuthOptionsTwo> configureOptions)
        {
            return builder.AddScheme<CustomAuthOptionsTwo, CustomAuthHandlerTwo>("MyScheme2", "MyAuth2", configureOptions);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      相关资源
      最近更新 更多