我使用AuthenticationHandler:DelegatingHandler在web api中实现了基本的身份验证和授权。
因此,在调用任何api之前,都会执行该处理程序中的代码,基本上检查用户是否经过身份验证。
每个api调用都会执行这个处理程序。现在我的问题是,对于一些api,如登录或注册等,用户没有登录,我不需要检查用户身份验证,我如何绕过它?
您不应该混淆身份验证和授权。
基本上,您的AuthenticationHandler
应该仅对用户进行身份验证,并且设置用户标识。
身份验证的目的是说这个用户是谁(经理、出纳员、匿名用户…)。你不应该拒绝这里的请求,这是为了授权。示例代码:
public class AuthHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
//authenticate with your data storage (user,password), or decrypt the information from request's token (I don't know what approach you're doing)
// here I hardcode just for demo
//If the user is authenticated (not an anonymous user)
//create a identity for that user and set the roles for
//the user. The roles could come from your db or your decrypted token depending on how you implement your code.
GenericIdentity MyIdentity = new ClaimsIdentity("MyUser");
String[] MyStringArray = {"Manager", "Teller"};
GenericPrincipal MyPrincipal = new GenericPrincipal(MyIdentity, MyStringArray);
//Set the authenticated principal here so that we can do authorization later.
Thread.CurrentPrincipal = MyPrincipal;
if (HttpContext.Current != null)
HttpContext.Current.User = MyPrincipal;
return await base.SendAsync(request, cancellationToken);
}
}
授权发生在验证用户是否有权访问某个功能的身份验证之后。这可以通过应用AuthorizeAttribute:来实现
- 关于动作方法
- 在控制器上所有操作方法都要求用户而不是匿名。您可以在每个操作方法中通过应用AllowAnonymousAttribute来覆盖它
- 通过将AuthorizeAttribute添加到应用程序筛选器集合进行全局设置。对于特定的操作方法,可以将相同的技术与AllowAnonymousAttribute一起使用。从链接中提取的示例代码:
在您的情况下,您可以:
- 将AuthorizeAttribute全局添加到应用程序筛选器集合中
- 根据经过身份验证的用户在
AuthHandler
中设置身份 - 在登录、注册操作方法上应用AllowAnonymousAttribute
旁注:当今最突出的授权方法是基于声明的安全性。如果你有时间,你应该花一些时间来调查一下。基本上,这个想法是类似的,只是我们使用声明而不是角色进行授权。
使用基于web api的声明,您可以将ClaimsAuthorizationManager子类化,通过重写CheckAccess
方法来实现您的授权规则。