为什么我需要设置一个DefaultForbidScheme [英] Why do i need to set a DefaultForbidScheme
问题描述
在WebAPI .net核心项目中,我创建了一个中间件类来验证api密钥.通过对其进行验证,它会检索密钥在invoke方法内具有的权限(用户或管理员).
In a WebAPI .net core project I have created a Middleware class that validates an api key. From validating it, it retrieves the permissions that the key has (user or admin) within the invoke method.
我通过一个开关将其设置为这样的原理
I pass it through a switch to set the principle like so
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;
}
在控制器上,我有方法
[Authorize(Roles = "Admin")]
On controllers methods I have
[Authorize(Roles = "Admin")]
验证经过身份验证的api密钥的作用
to validate the roles of an authenticated api key
如果用户具有管理原则,则按预期进行.但是,如果它具有用户或其他原理,那么我会收到关于
If the user has the admin principle it goes through as expected. However, if it has a user or other principle then I get an error about
没有DefaultForbidScheme
not having a DefaultForbidScheme
我到处搜索并通过客户计划将身份验证添加到我的startup.cs中
I googled around and added Authentication to my startup.cs with a customer scheme
services.AddAuthentication(options=> {
options.DefaultForbidScheme = "forbidScheme";
options.AddScheme<AuthSchemeHandle>("forbidScheme", "Handle Forbidden");
});
并创建了 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;
}
}
现在,如果该原则没有Admin,它将失败,并且没有错误,但是API返回的响应为200
,没有任何内容.我希望收到4xx
响应,并显示消息身份验证失败"
Now if the principle does not have Admin it fails without the error but the response that is returned on the API is 200
with no content. I was expecting a 4xx
response with the message "Failed Auth"
我只是在试图弄清为什么它看起来不像预期的那样固定",我不明白它是如何固定的.
I am just trying to work out why it is not as expected as although it seems "fixed" I do not understand how it has fixed it.
我应该有更好的方法吗?
Is there a better way that I should be doing this?
问候 标记
推荐答案
为什么它似乎不像预期的那样修复",所以我不明白它是如何修复的.
why it is not as expected as although it seems "fixed" I do not understand how it has fixed it.
当身份验证处理程序调用IAuthenticationHandler.ForbidAsync()
方法时,没有黑魔法.我们必须自己做相关的事情.简而言之,根据需要设置StatusCode=403
.
There's no dark magic when the authentication handler calls IAuthenticationHandler.ForbidAsync()
method. We have to do relevant things ourself. In short, setting the StatusCode=403
as your need.
public async Task ForbidAsync(AuthenticationProperties properties)
{
properties = properties ?? new AuthenticationProperties();
_context.Response.StatusCode = 403;
// ...
return Task.CompletedTask;
}
请注意,您不必返回Task.FromResult()
,因为它并不关心结果.
As a side note, you don't need return a Task.FromResult()
as it doesn't care about the result.
我应该有更好的方法吗?
Is there a better way that I should be doing this?
ASP.NET核心团队为我们提供了一个抽象类AuthenticationHandler
来处理身份验证.该抽象类具有 ForbidAsync(AuthenticationProperties properties)
(以及其他公共方法).因此,如下扩展该抽象类非常容易:
The ASP.NET Core Team provides us an abstract class AuthenticationHandler
to handle authentication. This abstract class has a built-in implementation for ForbidAsync(AuthenticationProperties properties)
(and also for other public methods). So it's much easy to extends this abstract class as below:
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();
}
}
最后,添加身份验证服务的配置:
Finally, add a configuration for authentication service:
services
.AddAuthentication(options=>{
options.DefaultAuthenticateScheme = "forbidScheme";
options.DefaultForbidScheme = "forbidScheme";
options.AddScheme<MyAuthenticationHandler>("forbidScheme", "Handle Forbidden");
});
它应该可以正常工作.
这篇关于为什么我需要设置一个DefaultForbidScheme的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!