通过《EnableCorsAttribute特性背后的故事》我们知道:由CorsPolicyProvider提供的CorsPolicy表示目标Action采用的资源授权策略,ASP.NET Web API最终需要利用它对具体的跨域资源请求实施授权检验并生成相应的CORS响应报头。在ASP.NET Web API的应用编程接口中,资源授权检验的结果通过类型CorsResult来表示。

一、CorsResult

CorsResult定义在命名空间“System.Web.Cors”下,表示资源提供者针对具体跨域资源请求进行授权检验得到的结果,最终写入响应的CORS报头均通过此对象来生成。如下面的代码片断所示,CorsResult依然具有与6个CORS响应报头对应的属性,通过其方法ToResponseHeaders方法的字典表示由此6个属性生成的CORS相应报头,字典对象的Key和Value分别表示报头名称和值。

   1: public class CorsResult

   2: {

   3:     public string            AllowedOrigin { get; set; }

   4:     public IList<string>     AllowedExposedHeaders { get; }

   5:     public IList<string>     AllowedHeaders { get; }

   6:     public IList<string>     AllowedMethods { get; }

   7:     public long?             PreflightMaxAge { get; set; }

   8:     public bool              SupportsCredentials { get; set; }

   9:     

  10:     public IList<string>     ErrorMessages { get; }

  11:     public bool              IsValid { get; }

  12:  

  13:     public virtual IDictionary<string, string> ToResponseHeaders();

  14: }

CorsResult具有一个布尔类型的属性IsValid表示请求是否通过资源授权检验。如果该属性返回False(没有通过资源授权检验),另一个相关的属性ErrorMessages会提供导致检验失败的原因。IsValid是一个只读属性,它的值取决于通过ErrorMessages属性表示的字符串列表是否为空。

二、CorsRequestContext

针对CORS的支持其实并不限于仅被使用在ASP.NET Web API上,用于根据提供的资源授权策略对跨域资源请求进行授权检验得引擎定义在程序集System.Web.Cors.dll中,定义在另一个程序集对于这些类型来说,除了CorsPolicy定义在程序集System.Web.Cors.dll,其余的类型均定义在程序集System.Web.Http.Cors.dll中的相关类型可以视为对这个核心CORS引擎的扩展。对于本节引入的类型来说,它具有的命名空间其实也体现了它所在的程序集。

对于ASP.NET Web API来说,CORS资源授权检验实施的目标是表示当请求的HttpRequestMessage对象,这个对象自然不可能使用在ASP.NET的核心CORS引擎中。对于后者,授权检验是针对一个System.Web.Cors.CorsRequestContext对象,它代表针对当前请求的上下文。如下面的代码片断所示,我们可以通过CorsRequestContext对象得到对应HTTP请求的地址(RequestUri)、主机名称(Host)和采用的HTTP方法(HttpMethod)。

   1: public class CorsRequestContext

   2: {

   3:     public Uri         RequestUri { get; set; }

   4:     public string      Host { get; set; }

   5:     public string      HttpMethod { get; set; }    

   6:    

   7:     public string          Origin { get; set; }

   8:     public bool            IsPreflight { get; }

   9:     public string          AccessControlRequestMethod { get; set; }

  10:     public ISet<string>    AccessControlRequestHeaders { get; }

  11:  

  12:     public IDictionary<string, object> Properties { get; }

  13: }

CorsRequestContext的Origin属性返回通过请求的“Origin”报头表示的源站点。我们可以利用其IsPreflight属性判断HTTP请求是否为一个预检请求,这里对预检请求的判断标准与我们前面演示实例采用的完全一致:采用HTTP-OPTIONS方法摒弃同时具有“Origin”和“Access-Control-Request-Method”报头。

对于针对预检请求的CorsRequestContext,我们可以通过其属性AccessControlRequestMethod和AccessControlRequestHeaders得到请求报头“Access-Control-Request-Method”和“Access-Control-Request-Headers”的值。通过另一个字典类型的只读属性Properties,我们可以将任意对象作为属性附加到该CorsRequestContext对象上。

三、CorsEngine

我们说ASP.NET 的核心CORS引擎定义在程序集System.Web.Cors.dll中,它主要体验为这个名为CorsEngine的对象,其主要的使命在于:根据提供的资源授权策略(通过CorsPolicy类型表示)针对具体的跨域资源请求(通过CorsRequestContext类型表示)实施授权检验并得到相应的授权结果(通过CorsResult表示)。所有的CorsEngine类型均实现System.Web.Cors.ICorsEngine接口,如下面的代码片断所示,跨域资源请求的授权检查就实现在其唯一的EvaluatePolicy方法中。

   1: public interface ICorsEngine

   2: {

   3:     CorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy);

   4: }

在程序集System.Web.Cors.dll中定义了唯一的实现了ICorsEngine接口,即具有如下定义的类型System.Web.Cors.CorsEngine。如下面的代码片断所示,CorsEngine类型定义了3个辅助的虚方法(TryValidateOrigin、TryValidateMethod 和TryValidateHeaders)分别针对请求的源站点以及请求采用的HTTP方法和自定义报头实施授权检验,其中后面两个方法是专门为预检请求设计的。

   1: public class CorsEngine : ICorsEngine

   2: {

   3:     public virtual CorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy);

   4:  

   5:     public virtual bool TryValidateOrigin(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result);

   6:     public virtual bool TryValidateMethod(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result);

   7:     public virtual bool TryValidateHeaders(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result); 

   8: }

CorsPolicyProviderFactory一样,ASP.NET Web API使用的CorsEngine需要注册到当前HttpConfiguration,注册的CorsEngine同样是被添加到HttpConfiguration的属性字典之中。CorsEngine的注册可以通过调用HttpConfiguration如下所示的扩展方法SetCorsEngine来完成。另一个扩展方法GetCorsEngine用于获取注册的CorsEngine,如果在调用此方法时CorsEngine尚未被注册,一个CorsEngine对象会被创建出来并自动注册到HttpConfiguration上。

   1: public static class CorsHttpConfigurationExtensions

   2: {

   3:     //其他成员

   4:     public static void SetCorsEngine(this HttpConfiguration httpConfiguration, ICorsEngine corsEngine);

   5:     public static ICorsEngine GetCorsEngine(this HttpConfiguration httpConfiguration);

   6: }

 

CORS系列文章

[1] 同源策略与JSONP

[2] 利用扩展让ASP.NET Web API支持JSONP

[3] W3C的CORS规范

[4] 利用扩展让ASP.NET Web API支持CORS

[5] ASP.NET Web API自身对CORS的支持: 从实例开始

[6] ASP.NET Web API自身对CORS的支持: CORS授权策略的定义和提供

[7] ASP.NET Web API自身对CORS的支持: CORS授权检验的实施

[8] ASP.NET Web API自身对CORS的支持: CorsMessageHandler

ASP.NET Web API自身对CORS的支持: CORS授权检验的实施的更多相关文章

  1. ASP.NET Web API自身对CORS的支持:从实例开始

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中我们通过自定义的HttpMessageHandler为ASP.NET Web API赋予了跨域资源共享的能力,具体来 ...

  2. JavaScript跨域调用、JSONP、CORS与ASP.NET Web API[共8篇]

    [第1篇] 同源策略与JSONP 浏览器是访问Internet的工具,也是客户端应用的宿主,它为客户端应用提供一个寄宿和运行的环境.而这里所说的应用,基本是指在浏览器中执行的客户端JavaScript ...

  3. 使用ASP.NET Web API自带的类库实现对CORS的支持(在开发中使用这种方式)(转载)

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中我们通过自定义的HttpMessageHandler为ASP.NET Web API赋予了跨域资源共享的能力,具体来 ...

  4. 在ASP.NET Web API中实现CORS(跨域资源共享)

    默认情况下,是不允许网页从不同的域访问服务器资源的,访问遵循"同源"策略的原则. 会遇到如下的报错: XMLHttpRequest cannot load http://local ...

  5. ASP.NET Web API 2.1支持Binary JSON(Bson)

    ASP.NET Web API 2.1内建支持XML.Json.Bson.form-urlencoded的MiME type,今天重点介绍下Bson.BSON是由10gen开发的一个数据格式,目前主要 ...

  6. 【ASP.NET Web API教程】2.1 创建支持CRUD操作的Web API

    原文 [ASP.NET Web API教程]2.1 创建支持CRUD操作的Web API 2.1 Creating a Web API that Supports CRUD Operations2.1 ...

  7. 通过扩展让ASP.NET Web API支持W3C的CORS规范

    让ASP.NET Web API支持JSONP和W3C的CORS规范是解决"跨域资源共享"的两种途径,在<通过扩展让ASP.NET Web API支持JSONP>中我们 ...

  8. ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事

    从编程的角度来讲,ASP.NET Web API针对CORS的实现仅仅涉及到HttpConfiguration的扩展方法EnableCors和EnableCorsAttribute特性.但是整个COR ...

  9. 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...

随机推荐

  1. Drools 函数学习

    Drools 函数学习 函数是定义在规则文件当中一代码块,作用是将在规则文件当中若干个规则都会用到的业务操作封装起来,实现业务代码的复用,减少规则编写的工作量.函数的编写位置可以是规则文件当中 pac ...

  2. response基本常识,不是很准确欢迎来纠正。

    相应客户端的回应. response.sendError(500,"抱歉你的电脑中毒了!!"); //重定向的相应码 resp.setStatus(302); //重定向的响应头 ...

  3. WebGL入门教程(一)-初识webgl

    一.WebGL和传统网页的区别: 普通网页组成成分:HTML.JavaScript: WebGL网页组成成分:HTML5.JavaScript和GLSL ES(着色器语言 OpenGL ES): 二. ...

  4. Python爬虫学习(10):Selenium的好基友PhantomJS

    上一节中我们学习了selenium,用python来操作浏览器,在做网页自动化测试的时候最好不过了 .如果我们来做爬虫用一个带界面的浏览器似乎不太好吧,那可咋办呢?别着急,下来我们要介绍的就是一款不带 ...

  5. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  6. Python 基础语法学习笔记

    以下运行结果均通过Python3.5版本实测! 1.列表转换为字典 a = ['a', 'b'] b = [1, 2] c = ['c','d'] print (dict([a,b,c])) 输出结果 ...

  7. System.getProperty()方法大全

    System.out.println("当前程序所在目录:" + System.getProperty("user.dir")); // 当前程序所在目录 Sy ...

  8. SpringMVC -- 注解

    @Entity -- 实体类@Table(name = "hat_province", catalog = "news") -- 对应的表name -- 表名c ...

  9. JDBC

    <java连接数据库> Class.forName("com.mysql.jdbc.Driver")--1:加载驱动 Connection conn=DriverMan ...

  10. 页面制作之HTML

    标签 常用属性 id class style title - <a href ="/" title="收藏">收藏</a>(用于hove ...