使用Core 1.1遵循@ blowdart的建议并实施自定义中间件:
https://stackoverflow.com/a/31465227/29821
它的工作原理如下:
这有点适用于2.0,除了如果令牌无效(上面的步骤2)并且从未添加声明我得到"没有指定authenticationScheme,并且没有找到DefaultChallengeScheme。"
所以现在我读到2.0中的auth改变了:
https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x
我在ASP.NET Core 2.0中做同样事情的正确途径是什么?我没有看到做真正自定义身份验证的示例。
答案 0 :(得分:165)
因此,经过漫长的一天尝试解决这个问题之后,我终于想出微软是如何让我们为核心2.0中的新单一中间件设置制作自定义身份验证处理程序。
在查看MSDN上的一些文档后,我发现了一个名为AuthenticationHandler<TOption>
的类,它实现了IAuthenticationHandler
接口。
从那里,我找到了一个完整的代码库,其中现有的身份验证方案位于https://github.com/aspnet/Security
其中一个内部显示了Microsoft如何实现JwtBearer身份验证方案。 (https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer)
我将大部分代码复制到一个新文件夹中,并清除了与JwtBearer
有关的所有内容。
在JwtBearerHandler
类(扩展AuthenticationHandler<>
)中,有Task<AuthenticateResult> HandleAuthenticateAsync()
的覆盖
我在旧的中间件中添加了通过自定义令牌服务器设置声明,并且仍然遇到一些权限问题,只是在令牌无效时吐出200 OK
而不是401 Unauthorized
并没有设立任何索赔。
我意识到我已经覆盖Task HandleChallengeAsync(AuthenticationProperties properties)
,无论出于何种原因,它都用于通过控制器中的[Authorize(Roles="")]
设置权限。
删除此覆盖后,代码已经运行,并且在权限不匹配时成功抛出了401
。
现在主要的一点是,现在您无法使用自定义中间件,您必须通过AuthenticationHandler<>
实现它,并且在使用时必须设置DefaultAuthenticateScheme
和DefaultChallengeScheme
services.AddAuthentication(...)
。
这是一个应该是什么样子的例子:
在Startup.cs / ConfigureServices()中添加:
services.AddAuthentication(options =>
{
// the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...)
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Scheme";
})
.AddCustomAuth(o => { });
在Startup.cs / Configure()中添加:
app.UseAuthentication();
创建一个新文件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);
}
}
创建一个新文件CustomAuthOptions.cs
public class CustomAuthOptions: AuthenticationSchemeOptions
{
public CustomAuthOptions()
{
}
}
创建一个新文件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();
}
}
答案 1 :(得分:3)
正如您所引用的文章所述,从Core 1.x到Core 2.0的身份发生了相当大的变化。主要的变化是远离中间件方法并使用依赖注入来配置自定义服务。这为定制更复杂的实现Identity提供了更大的灵活性。因此,您希望摆脱上面提到的中间件方法并转向服务。按照引用文章中的迁移步骤来实现此目标。首先将 app.UseIdentity 替换为 app.UseAuthentication 。 UseIdentity 已弃用,将来的版本将不再支持。有关如何插入自定义声明转换并对声明view this blog post执行授权的完整示例。