C# ASP.NET核心2.0身份验证中间件
Core 1.1遵循@blowdart的建议,实现了一个自定义中间件: 它是这样工作的:C# ASP.NET核心2.0身份验证中间件,c#,authentication,asp.net-core,asp.net-core-2.0,C#,Authentication,Asp.net Core,Asp.net Core 2.0,Core 1.1遵循@blowdart的建议,实现了一个自定义中间件: 它是这样工作的: 我跑了。从请求头中拾取令牌 验证令牌,如果有效,则生成包含多个声明的标识(ClaimsIdentity),然后通过HttpContext.User.AddIdentity()添加这些声明 在ConfigureServices using services.AddAuthorization中,我添加了一个策略来要求中间件提供的声明 在控制器/操作中,我将使用[Authorize(Roles=“中间件添加的某
在ASP.NET Core 2.0中,我做同样事情的正确途径是什么?我没有看到一个真正实现自定义身份验证的示例。正如您参考的文章所指出的,身份从Core1.x到Core2.0有很大的变化。主要的变化是不再使用中间件方法,而是使用依赖注入来配置定制服务。这为更复杂的实现定制标识提供了更大的灵活性。因此,您希望摆脱上面提到的中间件方法,转而使用服务。按照参考文章中的迁移步骤来实现这一目标。首先,将app.UseIdentity替换为app.UseAuthentication。UseIdentity已折旧,在将来的版本中将不受支持。有关如何插入自定义声明转换并对声明执行授权的完整示例,请参见。因此,经过一天的努力,我终于了解了Microsoft希望我们如何为core 2.0中新的单一中间件设置定制身份验证处理程序 在浏览了一些MSDN文档之后,我发现了一个名为
AuthenticationHandler
的类,它实现了iaAuthenticationHandler
接口
从那里,我找到了一个完整的代码库,其中包含位于
在其中一个示例中,它展示了Microsoft如何实现JWTBear身份验证方案。()
我将大部分代码复制到一个新文件夹中,并清除了所有与JwtBearer
有关的内容
在JwtBearerHandler
类(扩展了AuthenticationHandler
)中,有一个对Task HandleAuthenticateAsync()
我添加了我们的旧中间件,用于通过自定义令牌服务器设置声明,但仍然遇到一些权限问题,只是在令牌无效且未设置声明时抛出了200 OK
,而不是401 Unauthorized
我意识到我已经重写了Task HandleChallengeAsync(AuthenticationProperties)
,无论出于何种原因,它都用于通过控制器中的[Authorize(Roles=”“)]
设置权限
删除此覆盖后,代码正常工作,并且在权限不匹配时成功抛出了401
这样做的主要好处是,现在您不能使用自定义中间件,您必须通过AuthenticationHandler
实现它,并且必须在使用services.AddAuthentication(…)
时设置DefaultAuthenticateScheme
和DefaultChallengeScheme
下面是一个例子,说明这一切应该是什么样子:
在Startup.cs/ConfigureServices()中添加:
在Startup.cs/Configure()中添加:
创建一个新文件CustomAuthExtensions.cs
public static class CustomAuthExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
{
return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
创建一个新文件CustomAuthHandler.cs
internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
// store custom services here...
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package
return AuthenticateResult.NoResult();
}
}
内部类CustomAuthHandler:AuthenticationHandler
{
public CustomAuthHandler(IOptionsMonitor选项、iLogger工厂记录器、UrlEncoder编码器、ISystemClock时钟):基本(选项、记录器、编码器、时钟)
{
//在这里存储自定义服务。。。
}
受保护的重写异步任务handleAuthenticateAync()
{
//构建声明并将其置于“上下文”中;您需要导入Microsoft.AspNetCore.Authentication包
返回AuthenticateResult.NoResult();
}
}
试试这个链接,尽管上面写着2个方案,但它会让你了解身份验证。你能添加你的代码让我们看看吗?我知道我在core2.0中遇到了JWT的问题-是在Startupbook中移动JWT的一个案例吗?有一个关于如何在WebAPI应用程序中使用JWT的示例吗?很好的帖子,但我在编译代码时遇到了一些问题。缺少CustomAuthOptions和AuthenticateResult类型。您可以发布这些信息吗?您是否愿意在Github回购协议的代码中分享您的结论?请您解释一下DefaultAuthenticateScheme
和DefaultChallengeScheme
?我不明白为什么两者都用?它们之间的区别是什么?+1表示“从那里,我找到了一个完整的代码库,其中包含位于的现有身份验证方案。”只需看看ASP.NET团队是如何做到这一点的,然后再给出这个(非常优秀的)答案。我们中有没有人想过,有一天我们会问一些关于MS代码和实践的问题,而答案是“看看他们的代码库?”对于稍后进来的其他人,您的AuthExtension
需要位于Microsoft.Extensions.DependencyInjection
命名空间中。请参见此示例:
public static class CustomAuthExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
{
return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
public class CustomAuthOptions: AuthenticationSchemeOptions
{
public CustomAuthOptions()
{
}
}
internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
// store custom services here...
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package
return AuthenticateResult.NoResult();
}
}