开发者社区> 行者武松> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介:
+关注继续查看

通过《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


作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
TCP服务端开发为例--web开发不同url请求为何会走不同方法
拿java的web开发为例子,相信有很多小伙伴是做j2EE开发的,htpp请求,json数据传输都是工作中经常用的,查询请求,添加请求,修改请求前端配个url,例如https://localhost/intsmaze/user/add?name=intsmaze。
1136 0
第123天:移动web开发中的常见问题
一、函数库 underscoreJS _.template: /*取到模版当中的字符串*/ var pointTemplateStr = $('#point_template').
753 0
Kotlin + Spring Boot (Gradle) + React.js (Nowa) 集成 Web 开发
Kotlin + Spring Boot (Gradle) + React.js (Nowa) 集成 Web 开发 image.png image.
1070 0
React.js 集成 Kotlin Spring Boot 开发 Web 应用实例详解
React.js 集成 Kotlin Spring Boot 开发 Web 应用实例详解 image.png image.png 项目工程目录 ~/easykotlin/reakt$ tree .
1011 0
React.js 集成 Spring Boot 开发 Web 应用
React.js 集成 Spring Boot 开发 Web 应用 1. 创建工程 image.png reakt$ tree . . ├── build.
1548 0
wangEditor-基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、易用、开源免费(2)
1 DOCTYPE html> 2 3 4 5 6 wangEditor上传图片到服务器 7 8 9 10 11 12 13 14 15 16...
1143 0
Angular Web 开发使用PrimeNG的UI组件
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/inforstack/article/details/78856190 PrimeNG官网:点击打开链接 加载 PrimeNG在npm上可用,如果现有的应用程序运行以下命令将其下载到项目。
772 0
+关注
行者武松
杀人者,打虎武松也。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Web应用系统性能优化
立即下载
WEB浏览器中即将发生的安全变化
立即下载
API 网关实践
立即下载