【问题标题】:User is missing identities in policy with authentication scheme用户在具有身份验证方案的策略中缺少身份
【发布时间】:2020-09-28 15:07:53
【问题描述】:

我创建了一个 ASP.NET Core 3.1 应用程序,它使用 2 种身份验证类型 - cookie 和 JWT 承载。

我已经设置了一个方案,可以根据请求的路径将用户重定向到正确的方案:

.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = "smart";
    sharedOptions.DefaultChallengeScheme = "smart";
})
.AddPolicyScheme("smart", "Bearer Authorization or Cookie", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        var requestPath = context.Request.Path;

        if (CookiePolicyPathRegex.IsMatch(requestPath))
        {
            return CookieAuthenticationDefaults.AuthenticationScheme;
        }

        return JwtBearerDefaults.AuthenticationScheme;
    };
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOAuthServiceScheme(Configuration); // Custom handler for JWT

我这样设置授权策略:

options.AddPolicy(ApiPolicies.CookiePolicy, policy =>
{
    // policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
    policy.RequireAuthenticatedUser();
    policy.RequireRole(Roles.Access);
});

options.AddPolicy(ApiPolicies.JwtPolicy, policy =>
{
    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
    policy.RequireAuthenticatedUser();
});

这很好,正在触发正确的策略,但我有一个问题。在我的集成测试中,我使用了一个为 cookie 身份验证添加 ClaimsIdentity 的中间件:

public async Task Invoke(HttpContext context)
{
    //  Removed for brevity

    var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

    context.User = new ClaimsPrincipal(claimsIdentity);

    await _next(context);
}

中间件设置为在 Auth 中间件之前运行

ConfigureAdditionalMiddleware(app);

app.UseAuthentication();
app.UseAuthorization();

如果我从 cookie 策略中取消注释 // policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme); 部分,则授权部分看不到在中间件中创建的身份。如果我留下评论,身份就在那里,包括声明、身份验证类型和所有内容。如果我查看转发到两个身份验证方案的 PolicyScheme,身份就在那里。

我的问题是,为什么添加 CookieAuthenticationDefaults.AuthenticationScheme 会以某种方式隐藏使用相同身份验证类型创建的用户身份?

【问题讨论】:

  • 是否可以将中间件放在UseAuthentication 中间件之后,因此尚未设置身份?
  • 好点,我编辑了帖子以包含 Startup.cs 的那部分,但我认为它应该没问题。身份在转发到身份验证方案的方案中可见
  • 身份可以在UseAuthenticationUseAuthorization 中设置,请参阅这篇文章以了解更多关于UseAuthentication 究竟是什么stackoverflow.com/questions/48836688/…

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


【解决方案1】:

授权中间件将评估您的策略并运行将覆盖 user.Context 的身份验证逻辑

这里是相关代码sn-p(我删除并简化了代码以突出显示相关部分):

public virtual async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
{
    if (policy.AuthenticationSchemes != null && policy.AuthenticationSchemes.Count > 0)
    {
        var newPrincipal = await context.AuthenticateAsync(scheme).Principal;

        if (newPrincipal != null)
        {
            context.User = newPrincipal;
            return AuthenticateResult.Success(new AuthenticationTicket(newPrincipal, string.Join(";", policy.AuthenticationSchemes)));
        }
        else
        {
            context.User = new ClaimsPrincipal(new ClaimsIdentity());
            return AuthenticateResult.NoResult();
        }
    }
    ...
}

因此,如您所见,当您为策略定义方案时,您输入“if”语句(这将设​​置一个新的context.User,如果您注释该行,身份验证逻辑将不会运行并且您的自定义用户对象将在那里

【讨论】:

  • 非常感谢您的研究!我想它会是这样的。那么让它在测试中工作的唯一方法是制造一个实际的cookie并在请求中发送它?我希望能够继续在策略中添加该方案,以便将其与 cookie 选项联系起来。
  • Cookie 制作将很难构建,因为您必须了解 cookie 身份验证 + cookie 对称加密/解密密钥的内部结构。
猜你喜欢
  • 2020-07-03
  • 2018-08-03
  • 2020-10-13
  • 1970-01-01
  • 2019-06-12
  • 2015-06-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
相关资源
最近更新 更多