ASP.NET WEBAPI 的身份验证和授权

摘要:
身份验证WebApi假定身份验证发生在主机程序名中。在这种情况下,HTTP消息处理程序检查请求并设置主体对象。请考虑以下事项以决定是否使用消息处理程序进行身份验证:HTTP模块检查所有ASP.Net管道。消息处理程序只检查路由到Web API的请求。HTTP模块仅在IIS中可用。HTTP模块参与IIS日志记录、审核和其他功能。HttpContext。现在的用户这是特定于ASP.NET的。当用户验证失败时,它返回HTTP401状态代码。AuthorizationFilterAttribute,它不基于用户和角色的同步授权。

定义

身份验证(Authentication):确定用户是谁。

授权(Authorization):确定用户能做什么,不能做什么。

身份验证

WebApi 假定身份验证发生在宿主程序称中。对于 web-hosting,宿主是 IIS。这种情况下使用 HTTP Module 进行验证。

验证时,宿主会创建一个表示安全上下文的主体对象(实现 IPrincipal),将它附加到当前线程。主体对象包含一个存储用户信息的 Identity 对象。若验证成功,Identity.IsAuthenticated 属性将返回 true。

HTTP 消息处理程序(HTTP Message Handler)

可以用 HTTP 消息处理程序代替宿主进行身份验证。这种情况下,由 HTTP 消息处理程序检查请求并设置主体对象。

请考虑以下事项决定是否使用消息处理程序进行身份验证:

  • HTTP 模块检查所有经过 asp.net 管道的请求,消息处理程序只检查路由到 WebAPI的请求。
  • 可以为每个路由单独设置消息处理程序。
  • HTTP 模块仅在 IIS 中可用。消息处理程序则与宿主无关,在 web-hosting 和 self-hosting 中均可用。
  • HTTP 模块参与IIS 日志和审计等功能。
  • HTTP模块在管道之前运行,主体在消息处理程序运行之前不会设置,当响应离开 消息处理程序时,主体会恢复成原来的那个。

一般来说,不需要自承载时,HTTP 模块较好。

设置主体

进行自定义身份验证时,应在两个地方设置主体对象:

  • Thread.CurrentPrincipal,这是 .net 中设置线程主体的标准方式。
  • HttpContext.Current.User 这是特定于 ASP.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 不运行。
  • 在 action 内部,可以用 ApiController.User 属性获取主体对象,做进一步的控制。

[Authorize] 属性

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,基于用户和角色进行授权。
  • AuthorizationFilterAttribute,不基于用户和角色的同步授权。
  • IAuthorizationFilter,实现此接口执行异步授权逻辑。例如,授权逻辑中有对 IO 或网络的异步调用。(CPU-bound的授权逻辑更适合从 AuthorizationFilterAttribute 派生,这样不必写异步方法)。

下图是 AuthorizeAttribute 类层次

在 Action 中执行验证

可在控制器中检查 ApiController.User 属性,根据用户和角色使用不同的逻辑。

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

原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

免责声明:文章转载自《ASP.NET WEBAPI 的身份验证和授权》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java学习第十五章 之 Map、可变参数、Collections关于c#的连接池(以OracleConneciton为例)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WebApi管理和性能测试工具WebApiBenchmarks

WebApiBenchmark 说到WebApi管理和测试工具其实已经非常多的了,Postman、Swagger等在管理和维护上都非常出色;在性能测试方面也有不少的工具如:wrk,bombardier,http_load和ab等等。不过这些工具都具有单一性,管理和维护好的在性能测试上比较低效,对于性能测试好的在管理和维护上不理想!以下主要介绍一款基于dotn...

C#进阶系列——WebApi 跨域问题解决方案:CORS

  阅读目录 一、跨域问题的由来 二、跨域问题解决原理 三、跨域问题解决细节 1、场景描述 2、场景测试 四、总结 正文 前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题。本篇主要从实例的角度分享下CORS解决跨域问题一些细节。 WebApi系列文章 C#进阶系列——WebApi接口...

.NET Core:在ASP.NET Core WebApi中使用Cookie

一、Cookie的作用 Cookie通常用来存储有关用户信息的一条数据,可以用来标识登录用户,Cookie存储在客户端的浏览器上。在大多数浏览器中,每个Cookie都存储为一个小文件。Cookie表示为键/值对的形式,可以利用键来读取、写入或删除Cookie。 在ASP.NET Core中也可以使用Cookie来维护回话状态,包含回话ID的Cookie会随...

c# HttpWebResponse 调用WebApi

public static class WebApiCaller { public static string HttpPost(string url, string body) { try { //ServicePointManager...

C# WebApi 接口传参详解

本篇打算通过get、post、put、delete四种请求方式分别谈谈基础类型(包括int/string/datetime等)、实体、数组等类型的参数如何传递。 一、get请求 对于取数据,我们使用最多的应该就是get请求了吧。下面通过几个示例看看我们的get请求参数传递。 1、基础类型参数 ? 1 2 3 4 5 [HttpGet] publ...

webapi-1 给现有MVC 项目添加 WebAPI

1. 增加一个WebApi Controller, VS 会自动添加相关的引用,主要有System.Web.Http,System.Web.Http.WebHost,System.Net.Http 2. 在App_Start 下创建 WebApiConfig.cs 并注册路由 using System; using System.Collections...