【问题标题】:ASP.Net core 2: Default Authentication Scheme ignoredASP.Net 核心 2:忽略默认身份验证方案
【发布时间】:2018-04-19 08:25:35
【问题描述】:

我正在尝试在 ASP.Net Core 2 中构建一个自定义 AuthenticationHandler。按照 ASP.NET Core 2.0 authentication middleware 和 Why is Asp.Net Core Authentication Scheme mandatory 之类的主题,我已经创建了特定的类。注册过程如下:

services.AddAuthentication(
    options =>
    {
        options.DefaultScheme = Constants.NoOpSchema;
        options.DefaultAuthenticateScheme = Constants.NoOpSchema;
        options.DefaultChallengeScheme = Constants.NoOpSchema;
        options.DefaultSignInScheme = Constants.NoOpSchema;
        options.DefaultSignOutScheme = Constants.NoOpSchema; 
        options.DefaultForbidScheme = Constants.NoOpSchema;
    }
).AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });

如果特定控制器明确设置方案,一切正常:

[Authorize(AuthenticationSchemes= Constants.NoOpSchema)]
[Route("api/[controller]")]
public class IndividualsController : Controller

但我不想设置架构,因为它应该是动态添加的。一旦我删除了 Scheme 属性,就像这样:

[Authorize]
[Route("api/[controller]")]
public class IndividualsController : Controller

它不再起作用了。

我希望设置 DefaultScheme 属性可以完成这项工作。有趣的是,我没有找到任何关于这个话题的具体讨论。 我在这里做错了什么还是我的预期结果错了?

编辑:感谢您的提问,这对我帮助很大。当 CustomAuthHandler 没有到位时,我只使用了身份验证中间件使用的映射 DefaultScheme 似乎。因此,我必须始终添加 AuthenticationMiddleware。

Edit2:不幸的是,它仍然不起作用。为了加强我的问题:我像往常一样添加中间件:

app.UseAuthentication();
app.UseMvc();

现在我进入我的处理程序,它看起来像这样:

public class NoOpAuthHandler : AuthenticationHandler<NoOpAuthOptions>
{
    public const string NoOpSchema = "NoOp";

    public NoOpAuthHandler(IOptionsMonitor<NoOpAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync() => Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, NoOpSchema)));
}

但即使我总是返回成功,我也会得到 401。我想我必须深入挖掘并设置一些声明,但不幸的是,来自 Microsoft 的处理程序很难分析,因为它们包含大量代码。

【问题讨论】:

  • 您是否在中间件管道中添加了app.UseAuthentication()?
  • 删除AuthenticationSchemes时会出现什么错误?
  • CustomAuthHandler 是做什么的?
  • 我想你知道,但是你可以继承 authorize 属性来避免 AuthenticationSchemes= Constants.NoOpSchema

标签: c# authentication asp.net-core asp.net-core-mvc


【解决方案1】:

ASP.NET Core 2 答案

您必须设置与您的身份验证方案相关的默认授权策略:

services.AddAuthorization(options => {
  options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(Constants.NoOpSchema)
    .RequireAuthenticatedUser()
    .Build();
});

ASP.NET Core 3 答案

在 ASP.NET Core 3 中显然发生了一些变化,因此您需要创建一个扩展方法来添加您的身份验证处理程序:

public static class NoOpAuthExtensions
{
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, _ => { });
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(authenticationScheme, null, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<NoOpAuthOptions> configureOptions)
    {
        return builder.AddScheme<NoOpAuthOptions, NoOpAuthHandler>(authenticationScheme, displayName, configureOptions);
    }
}

并在您的 ConfigureServices 方法中使用它,如下所示:

services
  .AddAuthentication(NoOpAuthHandler.NoOpSchema)
  .AddNoOpAuth();

【讨论】:

  • 这对我有用。我不确定DefaultAuthenticateScheme 的实际用途,但它不是用于设置默认的 [Authorize] 方案。
【解决方案2】:

确保您的管道中有身份验证中间件并将其放在 MVC 之前。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ///

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });
    ///
}

更新

尝试在HandleAuthenticateAsync 方法中使用此代码。

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    List<Claim> claims = new List<Claim>();
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
    ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
    return AuthenticateResult.Success(authenticationTicket);
}

【讨论】:

  • 另一个注意事项,在 .NET Core 3/5 中,确保在 app.UseAuthorization() 之前拥有 app.UseAuthentication。我一天有 2 个小时 :)
  • @RenéSackers 当你救了我!谢谢!
【解决方案3】:

我为此受苦了好几个小时,在我的情况下,问题是默认的 AuthenticationMiddleware 类。 进一步来说; 如果您在请求管道中的自定义中间件中设置 ClaimsPrincipal,如下所示;

HttpContext.context.User = new ClaimsPrincipal(identity); 这将覆盖您的默认身份验证配置设置,

我做了什么来解决;删除自定义中间件并在 Startup.cs 的配置部分添加app.UseAuthentication();,并且授权属性检查配置部分中的默认设置;

这是我的;

services.AddAuthentication(x =>
            {
                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateLifetime = true,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero
                };
            });

【讨论】:

  • 这个答案帮助我发现 DefaultScheme 的设置值不起作用!我需要将 DefaultAuthenticateScheme 设置为我的方案,因此我的自定义身份验证处理程序将在每个使用 [Authorize(AuthenticationSchemes = MyAuthenticationConstants.Scheme)] 甚至 [Authorize] 属性装饰的请求天气控制器操作上执行
【解决方案4】:

在 .NET Core 3.1 中,我必须手动将 [Authorize(AuthenticationSchemes = "Bearer")] 而不是普通的 [Authorize] 添加到端点,才能使身份验证按预期运行。以下配置更改解决了该问题:

services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "Bearer";
    })

【讨论】:

    【解决方案5】:

    试试这个。

    services.AddAuthentication(
            options =>
            {
                options.DefaultAuthenticateScheme = "Cookie"
                options.DefaultChallengeScheme = Constants.NoOpSchema;
                options.DefaultSignInScheme = "Cookie";
            }
        )
        .AddCookie("Cookie")
        .AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 2017-01-04
      • 1970-01-01
      • 2011-04-19
      • 2018-07-24
      • 2019-08-05
      • 2021-06-26
      相关资源
      最近更新 更多