mar*_*777 6 .net-core asp.net-core
在 WebAPI .net 核心项目中,我创建了一个验证 api 密钥的中间件类。通过验证它,它检索密钥在 invoke 方法中拥有的权限(用户或管理员)。
我通过一个开关来设置原理
GenericIdentity identity = new GenericIdentity("API");
GenericPrincipal principle = null;
//we have a valid api key, so set the role permissions of the key
switch (keyValidatorRes.Role)
{
case Roles.User:
principle = new GenericPrincipal(identity, new[] { "User" });
context.User = principle;
break;
case Roles.Admin:
principle = new GenericPrincipal(identity, new[] { "Admin" });
context.User = principle;
break;
default:
principle = new GenericPrincipal(identity, new[] { "Other" });
context.User = principle;
break;
}
Run Code Online (Sandbox Code Playgroud)
在控制器方法上我有
[Authorize(Roles = "Admin")]
验证经过身份验证的 api 密钥的角色
如果用户有 admin 原则,它会按预期进行。但是,如果它有用户或其他原则,那么我会收到关于
没有 DefaultForbidScheme
我搜索了一下,并使用客户方案在我的 startup.cs 中添加了身份验证
services.AddAuthentication(options=> {
options.DefaultForbidScheme = "forbidScheme";
options.AddScheme<AuthSchemeHandle>("forbidScheme", "Handle Forbidden");
});
Run Code Online (Sandbox Code Playgroud)
并创建了AuthSchemeHandle
public class AuthSchemeHandle : IAuthenticationHandler
{
private HttpContext _context;
public Task<AuthenticateResult> AuthenticateAsync()
{
return Task.FromResult(AuthenticateResult.NoResult());
}
public Task ChallengeAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task ForbidAsync(AuthenticationProperties properties)
{
return Task.FromResult(AuthenticateResult.Fail("Failed Auth"));
}
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
_context = context;
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果原则没有 Admin,它会失败而不会出现错误,但 API 上返回的响应200没有内容。我期待收到4xx消息“身份验证失败”的回复
我只是想弄清楚为什么它不像预期的那样虽然看起来“固定”,但我不明白它是如何修复它的。
有没有更好的方法让我应该这样做?
问候马克
itm*_*nus 11
为什么它不像预期的那样虽然看起来“固定”我不明白它是如何修复它的。
身份验证处理程序调用IAuthenticationHandler.ForbidAsync()方法时没有黑魔法。我们必须自己做相关的事情。简而言之,StatusCode=403根据您的需要设置。
public async Task ForbidAsync(AuthenticationProperties properties)
{
properties = properties ?? new AuthenticationProperties();
_context.Response.StatusCode = 403;
// ...
return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,您不需要 return aTask.FromResult()因为它不关心结果。
有没有更好的方法让我应该这样做?
ASP.NET Core 团队为我们提供了一个抽象类AuthenticationHandler来处理身份验证。这个抽象类具有ForbidAsync(AuthenticationProperties properties)(以及其他公共方法)的内置实现。所以扩展这个抽象类很容易,如下所示:
public class MyAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public MyAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
return AuthenticateResult.NoResult();
}
}
Run Code Online (Sandbox Code Playgroud)
最后,为认证服务添加一个配置:
services
.AddAuthentication(options=>{
options.DefaultAuthenticateScheme = "forbidScheme";
options.DefaultForbidScheme = "forbidScheme";
options.AddScheme<MyAuthenticationHandler>("forbidScheme", "Handle Forbidden");
});
Run Code Online (Sandbox Code Playgroud)
它应该按预期工作。
| 归档时间: |
|
| 查看次数: |
1968 次 |
| 最近记录: |