2014 年 7 月更新
我最初的回答涵盖了 WebApi 1。WebApi 2 发生了一些变化,即现在IAuthenticationFilter
意味着您可以将身份验证逻辑移出DelegatingHandler
更优雅的部分。
这里有一个 Nuget 项目,它提供了 IAuthenticationFilter 的实现,并解释了它的介绍的一些背景。
OWIN 中间件现在可能是实现您的身份验证逻辑的最佳位置 - 这里有一个证书身份验证示例,并且在这篇博文中提供了基本身份验证 OWIN 中间件,前一个示例是首选示例,因为它演示了基AuthenticationHandler
类的使用。
关于的建议AuthorizationFilters
基本保持不变。
结束更新
通常...
用于DelegatingHandler
进行身份验证...即某人是谁。使用它来设置线程和用户上下文的原理,添加声明等。您也可以在此处放置授权逻辑,但在相当全局的范围内。我个人总是使用 AuthorizationFilters 进行授权。
用于AuthorizationFilters
将控制器和操作限制为特定人员。当您可以使用声明、主体、url 或 http 请求参数中的信息推断他们的许可时,将使用这些。默认授权过滤器可用于限制对匿名用户或角色的访问(如果在委托处理程序中设置) - 显然,如果需要,您也可以实现自己的 AuthorizationFilters。
当您需要使用消息内容对授权做出决定时偶尔使用ActionFilters
,例如您需要访问实体上的属性以决定他们是否有权访问(显然要小心这个(!))。
笔记:
在AuthorizationFilters
读取正文内容之前调用它们,因此它们无权访问消息正文来做出授权决定,这就是为什么ActionFilters
专门OnActionExecuting
使用 偶尔引发身份验证错误的原因。
所以
在您的场景中,我会简单DelegatingHandler
地获取您的标题并设置主体。
public class CustomAuthenticationMessageHandler : DelegatingHandler
{
public CustomAuthenticationMessageHandler ()
{
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
Authenticate(request);
return base.SendAsync(request, cancellationToken);
}
protected virtual void Authenticate(HttpRequestMessage request)
{
var authorisationHeader = request.Headers.Authorization;
if (authorisationHeader == null)
{
return;
}
//Ensure you are happy with the header contents then
{
var principal = new GenericPrincipal(//new Identity , //Roles);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
}
}
然后使用AuthorizationFilters
限制访问:
[Authorize]
public string Get()
{
}
[Authorize(Roles = "Admin")]
public string GetAdminOnly()
{
}
注册全局认证
config.MessageHandlers.Add(new CustomAuthenticationMessageHandler());
这意味着在每个请求中,主体都将设置为 null 或有效身份。它不会处理授权,即不会拒绝对任何控制器或操作的访问。
开始保护资源
使用标准或自定义 [Authorize] 属性来定位受保护的控制器和操作。或全球注册:
config.Filters.Add(new AuthorizeAttribute());
并且仅将您希望使用该 [AllowAnonymous]
属性不安全的控制器和操作列入白名单。
如果您只想对某些路由进行身份验证
然后你可以修改你DelegatingHandler
的一点来设置InnerHandler
路由到正确的控制器,例如
public CustomAuthenticationMessageHandler(HttpConfiguration configuration)
{
InnerHandler = new HttpRoutingDispatcher(configuration);
}
然后你可以像这样在你的路由上指定这个处理程序:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "myurl",
defaults: new {},
constraints: new {},
handler: new CustomAuthenticationHandler(config)
);