ASP.NET WEB API 中的认证和授权

中英文术语对照

  • Authentication - 认证,就是确定登录用户的身份。
  • Authorization - 授权,就是决定一个认证过的用户能执行什么操作。
  • Principal - 主体,表示一个代码运行在其上的安全上下文。
  • HTTP Module - HTTP模块,IIS中的模块
  • HTTP Message Handler - HTTP消息处理器
  • Identity - 身份,代表一个用户,类似身份证,主体中包含一个当前用户的身份
  • Host - WEB服务宿主,可以是IIS服务器,可以使自托管的服务进程

Authentication(用户认证)

ASP.NET WEB API中的用户认证可以通过HTTP模块和HTTP消息处理器两种方法实现。

1. 通过HTTP模块认证

你可以在项目中配置使用任意IIS内建的认证模块(匿名身份认证、Basic基本身份认证、Windows集成身份认证、Digest摘要式身份认证、Microsoft.NET Passport身份认证)。

认证用户时,会创建一个Principal(主体),该主体是一个IPrincipal对象,代表一个代码执行的安全上下文,通过调用属性Thread.CurrentPrincipal的设置方法将该主体设置到当前线程,主体包含一个关联的Identity(用户身份)对象,该对象包含用户信息,如果用户已经是认证通过的,则Identity.IsAuthenticated属性为true,对于匿名请求来说,该属性为false。

2. 通过HTTP消息处理器认证

如果不使用宿主提供的HTTP模块认证方法,我们也可以HTTP Message Handler来实现,这种情况下,HTTP消息处理器负责检查HTTP请求并设置Principal。我们应该什么时候使用消息处理器来处理身份验证呢?以下是我们应该权衡的要素:

  • HTTP模块能监视到所有通过ASP.NET管道的请求,而HTTP消息处理器只能监视路由到WEB API的请求。
  • 你可以在每个路由上设置一个消息处理器,针对不同的路由应用不同的认证策略。
  • HTTP模块特定于IIS服务器,而HTTP消息处理器对宿主是透明的,所以既可以用于IIS服务器托管环境也可以用于自托管环境。
  • HTTP模块能使用到IIS的日志、审计等等功能,而消息处理器不能。
  • HTTP模块在ASP.NET管道前期运行,而HTTP消息处理器认证时,只有执行到HTTP消息处理器是才会设置Principal,且当响应消息离开HTTP消息处理器后,Principal会被设置回默认值。

基本上来讲,如果你不需要支持服务自托管,HTTP模块是一个更好的选择,如果你需要支持自托管,那么应该考虑使用HTTP消息处理器。

Authorization(用户授权)

授权发生在ASP.NET处理管道的末端,靠近控制器的部分,这样能让你在获取资源存取权限时有更细粒度的选择。

授权过滤器(Authorization filters)运行在控制器动作之前,如果请求是未授权的,则过滤器返回错误响应,控制器动作不会被调用。在控制器动作内部,可以通过属性Api.Controller.User获取当前主体。以下代码演示了如何使用System.Web.Http.AuthorizeAttribute属性来指定授权。

    // 所有的动作都需要授权
    [Authorize]
    public class ValuesController : ApiController
    {
        public HttpResponseMessage Get(int id) { ... }
        public HttpResponseMessage Post() { ... }
    }

    // 指定的动作需要授权
    public class ValuesController : ApiController
    {
        public HttpResponseMessage Get() { ... }
    
        [Authorize]
        public HttpResponseMessage Post() { ... }
    }

    // 除了指定的动作不需要,剩下的所有动作都需要授权
    [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
    {
    }

    // 动作内部使用授权
    public HttpResponseMessage Get()
    {
        if (User.IsInRole("Administrators"))
        {
            // ...
        }
    }

你可能感兴趣的:(ASP.NET WEB API 中的认证和授权)