ASP.NET Web API身份验证和授权
英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
本文是作者所理解和翻译的内容。
这篇文章包括两部分:身份验证和授权。
- 身份验证用来确定一个用户的身份。例如,Alice用她的用户名和密码登陆系统,服务器用她的用户名和密码来确定她的身份。
- 授权是判断一个用户是否允许执行某一操作。例如,Alice有获取资源的许可,但不能创建资源。
身份验证
Web API有两种方式进行身份验证:在宿主程序中的身份验证和使用 HTTP Message Handlers进行身份验证。
如果你的Web API运行在IIS中,那么身份验证程序就是HTTP Modules,可以使用内置的asp.net身份验证模块进行身份验证,也可以自己写一个身份验证模块完成自定义身份验证。
当在宿主程序中进行身份验证时,宿主程序会创建一个principal对象,这个对象的类实现了IPrincipal接口,用来代表当前代码运行的安全上下文。宿主通过设置Thread.CurrentPrincipal 将主体附加到当前进程。principal包含一个关联用户信息的Identity 对象,如果用户验证通过,Identity.IsAuthenticated 属性返回true;对于匿名请求,IsAuthenticated 返回false。关于更多的principals信息,参见Role-Based Security。
使用HTTP Message Handlers 进行身份验证
你可以在 HTTP message handler中创建身份验证逻辑来代替使用宿主身份验证机制,在这种机制中,message handler检验Http请求并设置principal。
该在何时使用HTTP Message Handler进行身份验证呢?这里给出了一个这种的参考:
- 一个HTTP Module观察所有通过ASP.NET管道的请求;一个Message Handler只观察被路由处理的Web API请求。
- 你可以对每个路由设置一个Message Handler,这个方便了针对特殊的路由设置特殊的身份验证方案。
- HTTP Module是IIS特有的;Message Handler则与宿主无关,因此你可以同时在web-hosting和self-hosting中使用。
- HTTP Module参与IIS的登陆、审核等处理。
- HTTP Module在管道中更早的执行,如果你使用Message Handler进行身份验证,在handler执行前principal 没有准备好。此外,在response离开Message Handler后,principal 会被恢复到之前的principal 。
综上所述,如果你不需要支持self-hosting,HTTP Module回事更好的选择。如果你需要支持self-hosting,那就考虑使用Message Handler吧。
设置Principal
如果你的程序完成了一些自定义的身份验证逻辑,那么你必须设置爱两个地方的principal:
- Thread.CurrentPrincipal. 这个属性是在.NET中设置线程 principal的标准途径。
- HttpContext.Current.User. 这个属性是ASP.NET 专用的。
下面的代码展示了如何设置principal:
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
对于web-hosting,你必须在这两个地方食指principal,否则安全上下文可能会变得不一致。对于self-hosting,HttpContext.Current是null。为了确定你的代码与宿主无关,所以在赋值之前检查一下HttpContext.Current,就像上面的代码那样。
授权
授权发生在管道的后面一些,更接近于controller。它让你在授权访问资源是可以进行更细小粒度的操作。
- Authorization filters 在controller Action之前运行。如果请求未授权,filter返回一个错误的response,action不会被调用。
- 在Controller Action内部,你可以通过ApiController.User属性访问当前principal。例如你可能要根据用户来过滤一个资源列表,只返回属于该用户的资源。

使用[Authorize]属性
Web API 提供了一个内置的授权过滤器:AuthorizeAttribute。这个过滤器检查用户是否被授权,如果没有,则返回 http status code 401(Unauthorized),不会调用Action。
你可以添加将过滤器添加到globally,或Controller级别,或Action级别。
globally:要为每一个Web API请求添加约束,则在全局的过滤器列表中添加AuthorizeAttribute。
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new AuthorizeAttribute());
}
Controller:要约束一个特殊的controller的访问,则在controller上添加AuthorizeAttribute。
[Authorize]
public class ValuesController : ApiController
{
public HttpResponseMessage Get(int id) { ... }
public HttpResponseMessage Post() { ... }
}
Action:要约束一个特殊Action的访问,在Action上添加AuthorizeAttribute。
public class ValuesController : ApiController
{
public HttpResponseMessage Get() { ... } // Require authorization for a specific action.
[Authorize]
public HttpResponseMessage Post() { ... }
}
另外,你还可以约束一个controller访问的同时允许匿名访问特殊的Action,这需要使用[AllowAnonymous]属性。在下面的示例中,Post方法被约束了,而Get方法允许被匿名访问:
[Authorize]
public class ValuesController : ApiController
{
[AllowAnonymous]
public HttpResponseMessage Get() { ... } public HttpResponseMessage Post() { ... }
}
在上面的例子中,过滤器允许任何被验证的用户访问受约束的方法,只有匿名用户被拒绝。
你还可以限制一些特殊用户或特殊角色的访问:
// Restrict by user:
[Authorize(Users = "Alice,Bob")]
public class ValuesController : ApiController
{
} // Restrict by role:
[Authorize(Roles = "Administrators")]
public class ValuesController : ApiController
{
}
注意:Web API中的AuthorizeAttribute过滤器是在命名空间System.Web.Http中的,在MVC Controller中有一个相似的过滤器,定义在System.Web.Mvc中,他俩不能兼容使用。
自定义 Authorization Filters
一个自定义authorization filter衍生自一下几个类型:
- AuthorizeAttribute. 扩展这个类来完成基于当前用户和角色的授权逻辑。
- AuthorizationFilterAttribute. 扩展这个类完成同步的授权逻辑,这种方式必须要基于当前用户和角色。
- IAuthorizationFilter. 实现这个接口来完成异步的授权逻辑。例如,如果你的授权逻辑使用了异步的IO或网络调用(如果你的授权逻辑是CPU-Bound,那就和简单的衍生自AuthorizationFilterAttribute一样,因为你不需要写一个异步方法)
The following diagram shows the class hierarchy for the AuthorizeAttribute class.
下面的图片展示了AuthorizeAttribute的类层级:

在Controller Action中授权
有时候,你可能允许一个请求继续下去,但根据principal改变其行为。例如,你返回的信息会依赖用户角色发生改变。在Controller的方法中,你可以通过ApiController.user属性得到当前的principal。
public HttpResponseMessage Get()
{
if (User.IsInRole("Administrators"))
{
// ...
}
}
ASP.NET Web API身份验证和授权的更多相关文章
- asp.net Web API 身份验证 不记名令牌验证 Bearer Token Authentication 简单实现
1. Startup.Auth.cs文件 添加属性 1 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; ...
- 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
原文:使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)--第1部分 原文链接:https://www.codeproject.com/Articles/5160941/ASP- ...
- 基于JWT的web api身份验证及跨域调用实践
随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的 ...
- ASP.NET Web API模型验证以及异常处理方式
ASP.NET Web API的模型验证与ASP.NET MVC一样,都使用System.ComponentModel.DataAnnotations. 具体来说,比如有:[Required(Erro ...
- ASP.NET WEBAPI 的身份验证和授权
定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...
- ASP.NET Web API 安全验证之摘要(Digest)认证
在基本认证的方式中,主要的安全问题来自于用户信息的明文传输,而在摘要认证中,主要通过一些手段避免了此问题,大大增加了安全性. 1.客户端匿名的方式请求 (无认证) HTTP/ Unauthorized ...
- Web API 身份验证 不记名令牌验证 Bearer Token Authentication
1. Startup.Auth.cs文件 添加属性 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; p ...
- c# api身份验证和授权
授权 1. 全局 config.Filters.Add(new AuthorizeAttribute()); 2.控制器级别 [Authorize] public class HelloControl ...
- asp.net web api 权限验证的方法
思路:客户端使用header或者form讲验证信息传入api,在权限验证过滤中进行处理,代码示例: 定义过滤器 public class ApiFilter1 : System.Web.Http.Au ...
随机推荐
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- CoreAnimation-03-隐式动画
简介 每个UI控件,默认自动创建一个图层(根图层),即每个UI控件对应于至少一个图层 可以手动创建图层,这些图层为非根图层 对非根图层的某些属性(标记为Animatable的属性)进行修改,默认会自动 ...
- block的用法以及block和delegate的比较(转发)
看到一篇写的关于block和delegate放在一起来方便大家理解的文章,感觉不错,就推荐给大家来看一下. 代理设计模式对于iOS开发的人来说肯定很熟悉了,代理delegate就是委托另一个对象来帮忙 ...
- Effective Java 52 Refer to objects by their interfaces
Principle If appropriate interface types exist, then parameters, return values, variables, and field ...
- 学习HTML5必读之《HTML5设计原理》
引子:很久前看过的一遍受益匪浅的文章,今天再次转过来,希望对学习HTML5的朋友有所帮助. 今天我想跟大家谈一谈HTML5的设计.主要分两个方面:一方面,当然了,就是HTML5.我可以站在这儿只讲HT ...
- LightSpeed使用指南
LightSpeed 是一个最高性能的 .NET 领域建模和 O/R 映射框架,第一级别的 LINQ 支持.Visual Studio 2008/2010 设计器集成,是一个著名的高性能框架.[注:收 ...
- Java中关于WeakReference和WeakHashMap的理解
新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: private static String test(){ String a = new String("a&quo ...
- 烂泥:ubuntu安装vmtools
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 最近由于工作需要,需要使用桌面版的linux系统,所以就选择了ubuntu.同时为了方便使用,就在VM中安装ubuntu. 但是为了文件以及操作的方便就 ...
- JavaScript中的直接量与初始器的区别
很多代码优化及公司规范都会提到 写对象不应该 var obj = new Object() 而应该 var obj = {} 写数组不应该 var arr = new Array() 而应该 var ...
- EXCEL IF 函数 模糊查询
A列都是产品名,比如衬衫,长袖衬衫,短袖衬衫,短裙,长裙 搜索A列的产品名,凡是含有“衬衫”的一律在B列对应行输出“衬衫”,凡是含有“裙”字的一律输出“裙子”在B列对应行,请教一下怎么写函数,本来用I ...