一般来说,不需要自承载时,HTTP 模块较好。
进行自定义身份验证时,应在两个地方设置主体对象:
Thread.CurrentPrincipal,这是 .net 中设置线程主体的标准方式。private void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } }
采用 web-hosting 时,必须同时设置两处,避免安全上下文不一致。对于 self-hosting,HttpContext.Current 为 null,所以设置之前应进行检查。
授权发生在管道中更接近 controller 的位置。
授权筛选器(Authorization filter)在 action 之前运行。若请求未授权,返回错误,action 不运行。
AuthorizeAttribute 是内置的授权筛选器。用户未通过身份验证时,它返回 HTTP 401 状态码。可以在全局,控制和 action 三个级别应用它。
在全局级别应用:
public static void Register(HttpConfiguration config) { config.Filters.Add(new AuthorizeAttribute()); }
在控制器级别应用:
[Authorize] public class ValuesController : ApiController { public HttpResponseMessage Get(int id) { ... } public HttpResponseMessage Post() { ... } }
在 Action 级别应用:
public class ValuesController : ApiController { public HttpResponseMessage Get() { ... } [Authorize] public HttpResponseMessage Post() { ... } }
在控制器上应用 [Authorize] 时,可以在 Action 上应用 [AllowAnonymous] 取消对某个 Action 的授权要求。上面的代码可以改成下面的形式:
[Authorize] public class ValuesController : ApiController { [AllowAnonymous] public HttpResponseMessage Get() { ... } public HttpResponseMessage Post() { ... } }
指定用户和角色进行限制:
// 按用户限制访问 [Authorize(Users="Alice,Bob")] public class ValuesController : ApiController { } // 按角色限制访问 [Authorize(Roles="Administrators")] public class ValuesController : ApiController { }
用于 WebAPI 的 AuthorizeAttribute 位于 System.Web.Http 命名空间。在 System.Web.Mvc 命名空间中有一个同名属性,不可用于 WebAPI。
可从以下类型派生自定义授权筛选器
AuthorizeAttribute,基于用户和角色进行授权。下图是AuthorizeAttribute类层次
可在控制器中检查 ApiController.User 属性,根据用户和角色使用不同的逻辑。
public HttpResponseMessage Get() { if (User.IsInRole("Administrators")) { // ... } }