C# ASP.Net core 2:忽略默认身份验证方案
我正在尝试在ASP.NETCore2中构建一个自定义AuthenticationHandler。在像和这样的主题之后,我创建了特定的类。注册过程如下所示:C# ASP.Net core 2:忽略默认身份验证方案,c#,authentication,asp.net-core,asp.net-core-mvc,C#,Authentication,Asp.net Core,Asp.net Core Mvc,我正在尝试在ASP.NETCore2中构建一个自定义AuthenticationHandler。在像和这样的主题之后,我创建了特定的类。注册过程如下所示: services.AddAuthentication( options => { options.DefaultScheme = Constants.NoOpSchema; options.DefaultAuthenticateScheme = Constants.NoOpSchema;
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]
[Route("api/[controller]")]
public class IndividualsController : Controller
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)));
}
services
.AddAuthentication(NoOpAuthHandler.NoOpSchema)
.AddNoOpAuth();
但是我不想设置模式,因为它应该被动态添加。一旦我移除Scheme属性,如下所示:
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]
[Route("api/[controller]")]
public class IndividualsController : Controller
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)));
}
services
.AddAuthentication(NoOpAuthHandler.NoOpSchema)
.AddNoOpAuth();
它不再工作了
我希望,设置DefaultScheme属性可以完成这项工作。有趣的是,我没有发现关于这个话题的任何具体讨论。
我是做错了什么,还是我的预期结果错了
编辑:谢谢你的提问,这对我帮助很大。似乎身份验证中间件正在使用映射DefaultScheme,而我只在CustomAuthHandler不存在时使用它。因此,我必须始终添加AuthenticationMiddleware
Edit2:不幸的是,它仍然不起作用。为了加强我的问题:我像往常一样添加中间件:
app.UseAuthentication();
app.UseMvc();
现在我进入我的处理器,它看起来像这样:
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]
[Route("api/[controller]")]
public class IndividualsController : Controller
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)));
}
services
.AddAuthentication(NoOpAuthHandler.NoOpSchema)
.AddNoOpAuth();
public类NoOpAuthHandler:AuthenticationHandler
{
public const string NoOpSchema=“NoOp”;
public NoOpAuthHandler(IOptionsMonitor选项、iLogger工厂记录器、UrlEncoder编码器、ISystemClock时钟):基本(选项、记录器、编码器、时钟)
{
}
受保护的覆盖任务handleAuthenticationAsync()=>Task.FromResult(AuthenticateResult.Success)(新的AuthenticationTicket(Context.User,NoOpSchema));
}
但即使我总是成功,我也会得到401。我认为我必须更深入地挖掘,并设定一些声明,但不幸的是,来自Microsoft的处理程序很难分析,因为它们包含大量代码。确保您的管道中有身份验证中间件,并将其放在MVC之前
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
///
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
///
}
更新
尝试在handleAuthenticationAsync
方法中使用此代码
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);
}
protectedoverride异步任务handleAuthenticationAsync()
{
列表声明=新列表();
ClaimsIdentity ClaimsIdentity=新的ClaimsIdentity(索赔,Scheme.Name);
ClaimsPrincipal ClaimsPrincipal=新的ClaimsPrincipal(索赔实体);
AuthenticationTicket AuthenticationTicket=新的AuthenticationTicket(claimsPrincipal,Scheme.Name);
返回AuthenticateResult.Success(authenticationTicket);
}
ASP.Net核心2答案
您必须设置与身份验证方案关联的默认授权策略:
services.AddAuthorization(options => {
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(Constants.NoOpSchema)
.RequireAuthenticatedUser()
.Build();
});
ASP.Net核心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);
}
}
试试这个
services.AddAuthentication(
options =>
{
options.DefaultAuthenticateScheme = "Cookie"
options.DefaultChallengeScheme = Constants.NoOpSchema;
options.DefaultSignInScheme = "Cookie";
}
)
.AddCookie("Cookie")
.AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });
services.AddAuthentication(
选项=>
{
options.DefaultAuthenticateScheme=“Cookie”
options.DefaultChallengeScheme=Constants.NoOpSchema;
options.defaultSignenscheme=“Cookie”;
}
)
.AddCookie(“Cookie”)
.AddScheme(Constants.NoOpSchema,“自定义身份验证”,o=>{});
我经历了几个小时,在我的例子中,问题是默认的AuthenticationMiddleware类。
更具体地说;
如果您在请求管道中的自定义中间件中设置ClaimsPrincipal,如下所示
HttpContext.context.User=newclaimsprincipal(标识)代码>
这将覆盖默认的身份验证配置设置
我做了什么来解决问题;删除自定义中间件并添加app.UseAuthentication(),Authroize属性检查Configure部分中设置为默认值的内容
这是我的
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
};
});
在.NET Core 3.1中,我必须手动向端点添加[Authorize(authorization(authorizationschemes=“Bearer”)]
,而不是简单的[Authorize]
,以使身份验证如我所期望的那样发挥作用。以下配置更改解决了该问题:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Bearer";
})
您是否在中间件管道中添加了app.UseAuthentication()
?删除AuthenticationSchemes
时会出现什么错误?CustomAuthHandler做什么?我相信您知道,但您可以继承authorize属性以避免AuthenticationSchemes=Constants.NoOpSchemaThis对我有效。我不确定DefaultAuthenticateScheme
的实际用途,但它不是用于设置默认的[Authorize]方案。另一个注意事项是,在.NET Core 3/5中,请确保在app.UseAuthorization()
之前有app.UseAuthorization
。我每天有两个小时:)