Support for CORS by ASP. NET Web APIs: The Story Behind the EnableCorsAttribute feature,

Source: Internet
Author: User
Tags string methods

Support for CORS by ASP. NET Web APIs: The Story Behind the EnableCorsAttribute feature,

From the programming point of view, the implementation of ASP. NET Web API for CORS only involves the extended Methods EnableCors and EnableCorsAttribute of HttpConfiguration. However, the entire CORS system is not limited to this. There are a series of types hidden behind them. We will use the remaining content in this chapter to fully describe this, today, we will discuss the story behind the EnableCorsAttribute feature used to define CORS authorization policies.

Directory
I. CorsPolicy
Ii. CorsPolicyProvider
Iii. CorsPolicyProviderFactory
4. Registration of CorsPolicyProviderFactory
V. Summary

I. CorsPolicy

By applying the EnableCorsAttribute feature to the HttpController type or defining an Action method, we can define corresponding authorization policies for the provided resources. ASP. NET Web APIs use these policies to parse requests (including pre-check requests) and generate corresponding CORS response headers. In the Application Programming Interface of ASP. NET Web APIs, CORS authorization policies are represented by CorsPolicy.

Based on the W3C CORS specification, we know that the authorization policy for cross-origin resources not only requires the requested source site to be trustworthy, it also involves the HTTP Method Used for the request, the custom header and user creden。 carried, and the authorization for the custom response header. In addition, in order to avoid frequent browser precheck requests, the browser can cache the response results, and this involves controlling the cache expiration time. In general, these authorization policies are embodied in the following six CORS response headers.

  • Access-Control-Allow-Origin
  • Access-Control-Expose-Headers
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Max-Age
  • Access-Control-Allow-Credentials

In the Application Programming Interface of ASP. NET Web API, authorization policies centered around these six CORS response headers are represented by the System. Web. Cors. CorsPolicy type. CorsPolicy has the following six attributes that exactly correspond to the preceding six CORS response headers.

   1: public class CorsPolicy
   2: {
3: // other members
   4:     public IList<string>     Origins { get; }
   5:     public IList<string>     ExposedHeaders { get; }
   6:     public IList<string>     Headers { get; }
   7:     public IList<string>     Methods { get;; }
   8:     public long?             PreflightMaxAge { get; set; }
   9:     public bool              SupportsCredentials { get; set; }
  10: }

In addition to the preceding six attributes, CorsPolicy also has the following three Boolean attributes (AllowAnyOrigin, AllowAnyHeader, and AllowAnyMethod ), they indicate whether all origin sites, custom request headers, and HTTP methods are supported.

   1: public class CorsPolicy
   2: {
3: // other members
   4:     public bool AllowAnyOrigin { get; set; }
   5:     public bool AllowAnyHeader { get; set; }
   6:     public bool AllowAnyMethod { get; set; }
   7: }

 

Ii. CorsPolicyProvider

As the basis for cross-origin resource requests to perform authorization checks, and the CorsPolicy object used to generate the corresponding CORS header is provided through another object named CorsPolicyProvider. All CorsPolicyProvider types implement the interface System. web. http. cors. ICorsPolicyProvider. As shown in the following code snippet, the unique method GetCorsPolicyAsync of this interface obtains the CorsPolicy object representing the CORS authorization policy based on the HttpRequestMessage object representing the previous request.

   1: public interface ICorsPolicyProvider
   2: {
   3:     Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);
   4: }

In fact, the System. Web. Http. CORS. EnableCorsAttribute that is used to define the Cors authorization policy on the target HttpController type or the Action method is one of the implementers of the ICorsPolicyProvider interface. As shown in the following code snippet, EnableCorsAttribute also has six attributes for the CORS response header. In the implemented GetCorsPolicyAsync method, It initializes the returned CorsPolicy object through these six attributes.

   1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=false)]
   2: public sealed class EnableCorsAttribute : Attribute, ICorsPolicyProvider
   3: {    
   4:     public EnableCorsAttribute(string origins, string headers, string methods);
   5:     public EnableCorsAttribute(string origins, string headers, string methods,string exposedHeaders);
   6:  
   7:     public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);
   8:     
   9:     public IList<string> Origins { get; }
  10:     public IList<string> ExposedHeaders { get; }
  11:     public IList<string> Headers { get; }
  12:     public IList<string> Methods { get; }
  13:     public long          PreflightMaxAge { get; set; }
  14:     public bool          SupportsCredentials { get; set; }
  15: }

The authorized source site and the allowed custom request headers and HTTP methods, as well as the custom Response Headers exposed to the client JavaScript program, can be specified directly through the constructor parameters. For these four parameters, we can specify a single value (such as origin = "http://www.artech.com") or a list separated by commas (such as origin = "http://www.artech.com, http://www.jinnan.me "). In addition to exposedHeaders, we can also specify "*" as its parameter value, which means that no restrictions are imposed on this, they control the generation of three corresponding Boolean attribute values (AllowAnyOrigin, AllowAnyHeader, and AllowAnyMethod) of the CorsPolicy object ).

In addition to the EnableCorsAttribute feature, the "System. Web. Http. Cors" namespace also defines another relative feature DisableCorsAttribute. As the name suggests, if the disablecorsattri。 feature is applied to an HttpController type or an Action method defined in it, the target HttpController or Action does not support cross-origin resource sharing. As shown in the following code snippet, no specific CorsPolicy is returned in the implemented GetCorsPolicyAsync method.

   1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=false)]
   2: public sealed class DisableCorsAttribute : Attribute, ICorsPolicyProvider
   3: {
   4:     public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   5:     {
   6:         return Task.FromResult<CorsPolicy>(null);
   7:     }
   8: }

Because the CorsPolicyProvider feature of the application in the Action method has a better priority than the feature of the application in the HttpController type, for an HttpController type that defines many Action methods, if most of the Action methods need to support cross-origin resource sharing and have the same resource Authorization Policy, you can apply the EnableCorsAttribute feature directly on the HttpController type and make corresponding settings. For actions that do not support cross-origin resource sharing, simply apply the DisableCorsAttribute feature to the corresponding method. If an Action has special authorization requirements, you can use the EnableCorsAttribute feature of the Application for targeted settings. And vice versa.

Iii. CorsPolicyProviderFactory

CorsPolicyProvider is used to provide CorsPolicy objects used to describe CORS authorization policies. It is created through CorsPolicyProviderFactory. All CorsPolicyProviderFactory types implement the interface System. Web. Http. Cors. Handler. As shown in the following code snippet, GetCorsPolicyProvider provides the corresponding CorsPolicyProvider object based on the HttpRequestMessage object representing the current request.

   1: public interface ICorsPolicyProviderFactory
   2: {
   3:     ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
   4: }

Because the two specific CorsPolicyProvider types (EnableCorsAttribute and DisableCorsAttribute) provided are both features, ASP. NET Web APIs define CorsPolicyProviderFactory of the next annotation type to provide the corresponding CorsPolicyProvider in the form of parsing features.

   1: public class AttributeBasedPolicyProviderFactory : ICorsPolicyProviderFactory
   2: {    
   3:     public virtual ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
   4:     public ICorsPolicyProvider DefaultPolicyProvider { get; set; }
   5: }

The implementation of CorsPolicyProvider in the GetCorsPolicyProvider method is simple: it directly uses the HttpActionSelector registered on the current ServicesContainer to obtain the HttpActionDescriptor object used to describe the target Action according to the current request, then, call its GetCustomAttributes <T> method to obtain the first feature that implements the ICorsPolicyProvider interface applied to the corresponding Action method. If such a feature does not exist, obtain the HttpControllerDescritor object of the HttpController type where the description is located. In the same way, obtain the first feature of the ICorsPolicyProvider interface applied to the target HttpController type.

Concerning the selection of target actions, the core details are worth noting: if the current request is not a real cross-origin resource request, instead, it is only a Preflight Request that uses "OPTIONS" as the HTTP method. The registered HttpActionSelector cannot select the target Action based on the current Request, therefore, you must replace the HTTP Method of the request with the HTTP method used by the real cross-origin resource request. We know from the above introduction to the W3C CORS specification that this HTTP Method can be obtained through the "Access-Control-Request-Method" header of the pre-check Request. In fact, we have demonstrated this in the previous "Implementing CORS through custom HttpMessageHandler" instance.

According to the definition of AttributeBasedPolicyProviderFactory given above, apart from the implementation method GetCorsPolicyProvider, it also has a DefaultPolicyProvider attribute. This attribute indicates the default CorsPolicyProvider. If no feature implementing the ICorsPolicyProvider interface is applied to the target Action Method and Its HttpController type, this attribute will be used as the return value of the GetCorsPolicyProvider method.

4. Registration of CorsPolicyProviderFactory

The CorsPolicyProviderFactory used by ASP. NET Web API by default needs to be registered to the current HttpConfiguration. Specifically, registering CorsPolicyProviderFactory is actually saving it to the dictionary represented by the Properties attribute of the current HttpConfiguration. You can use the extension method SetCorsPolicyProviderFactory shown in HttpConfiguration to register CorsPolicyProviderFactory.

Another extension method, GetCorsPolicyProviderFactory, is used to obtain the successfully registered CorsPolicyProviderFactory. If the method CorsPolicyProviderFactory has not been registered, an AttributeBasedPolicyProviderFactory object will be created and registered to HttpConfiguration.

   1: public static class CorsHttpConfigurationExtensions
   2: {
3: // other members
   4:     public static ICorsPolicyProviderFactory GetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration);
   5:     public static void SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
   6: }
V. Summary

To sum up, CorsPolicy is used to describe a specific CORS resource Authorization Policy, which is provided by CorsPolicyProvider, and the latter is created through CorsPolicyProviderFactory. The UML shown in the right figure reveals the relationships between CorsPolicy, CorsPolicyProvider, and CorsPolicyProviderFactory interfaces and classes. For these types, except CorsPolicy is defined in the assembly System. Web. Cors. dll, other types are defined in the assembly System. Web. Http. Cors. dll.

 

CORS articles
[1] same-origin policy and JSONP
[2] using extensions to enable ASP. NET Web APIs to support JSONP
[3] W3C CORS specifications
[4] using extensions to enable ASP. NET Web APIs to support CORS
[5] Support for CORS by ASP. NET Web APIs: Starting from the instance
[6] Support for CORS by ASP. NET Web APIs: definition and provision of CORS authorization policies
[7] Support for CORS by ASP. NET Web APIs: Implementation of CORS authorization Verification
[8] CORS support for ASP. NET Web APIs: CorsMessageHandler

Reference page: http://qingqingquege.cnblogs.com/p/5933752.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.