ASP.NET Web API身份验证和授权

简介:

身份验证

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。例如你可能要根据用户来过滤一个资源列表,只返回属于该用户的资源。

image

使用[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的类层级:

image

在Controller Action中授权

有时候,你可能允许一个请求继续下去,但根据principal改变其行为。例如,你返回的信息会依赖用户角色发生改变。在Controller的方法中,你可以通过ApiController.user属性得到当前的principal。

public HttpResponseMessage Get()
{
    if (User.IsInRole("Administrators"))
    {
        // ...
    }
}

ps. 勉强的翻译了一下这篇文章的内容,就当是学习的笔记吧。




本文转自齐师傅博客园博客,原文链接:http://www.cnblogs.com/youring2/archive/2013/03/09/2950992.html,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 开发框架 NoSQL
ASP.NET WEB——项目中Cookie与Session的用法
ASP.NET WEB——项目中Cookie与Session的用法
35 0
|
2月前
|
开发框架 前端开发 .NET
ASP.NET WEB——项目创建与文件上传操作
ASP.NET WEB——项目创建与文件上传操作
46 0
|
3月前
|
域名解析 缓存 Linux
如何让你的.NET WebAPI程序支持HTTP3?
如何让你的.NET WebAPI程序支持HTTP3?
47 2
如何让你的.NET WebAPI程序支持HTTP3?
|
2月前
|
SQL 开发框架 .NET
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
67 0
|
2月前
|
SQL 开发框架 前端开发
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
34 0
|
2月前
|
SQL 开发框架 .NET
ASP.NET Web——GridView完整增删改查示例(全篇幅包含sql脚本)大二结业考试必备技能
ASP.NET Web——GridView完整增删改查示例(全篇幅包含sql脚本)大二结业考试必备技能
33 0
|
4月前
|
Python
Python Web 开发: 如何在 Flask 中实现用户认证和授权?
Python Web 开发: 如何在 Flask 中实现用户认证和授权?
|
4月前
|
Web App开发 开发框架 .NET
asp.net基于WEB层面的云LIS系统平台源码
结合当今各检验科管理及实验室规模的不同状况,充分吸收当今IT科技的最新成就,开发出以高度产品化、功能强大、极易实施操作、并不断升级换代为主要特点的LIS系统。彻底解决检验科的信息孤岛,全面实现全院信息互通互联、高度共享,并为检验科的规范化管理提供了有力工具。
41 0
|
14天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
21天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。