提问者:小点点

ASP.Net 核心 2:默认身份验证方案被忽略


我正在尝试在 ASP.Net Core 2中构建一个自定义身份验证处理程序。跟进 ASP.NET 核心 2.0 身份验证中间件和为什么 Asp.Net 核心身份验证方案是必需的主题,我创建了特定的类。注册发生如下:

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财产可以完成这项工作。有趣的是,我没有发现任何关于这个话题的具体讨论。我是在这里做错了什么,还是我预期的结果错了?

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

编辑2:可惜还是不行。为了加强我的问题:我像往常一样添加中间件:

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分。我想我必须更深入地挖掘并设置一些声明,但不幸的是,微软的Handlers很难分析,因为它们包含很多代码。


共3个答案

匿名用户

ASP.NET 核心2答案

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

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

ASP.NETCore 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();

匿名用户

确保您的管道中有身份验证中间件,并将其放在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);
}

匿名用户

我忍受了几个小时,在我的情况下,问题是默认的身份验证中间件类。

更具体地说;如果在请求管道中的自定义中间件中设置声明主体,如下所示;

< code > httpcontext . context . user = new ClaimsPrincipal(identity);这将覆盖您的默认身份验证配置设置,

我做了什么来解决;删除自定义中间件并添加应用。使用身份验证();在 配置部分 启动.cs 和 授权 属性检查配置部分中设置的任何内容作为默认值;

这是我的;

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
        };
    });

相关问题