接上篇的允許跨域
4.CORS 策略(Policy)的選項
這里講解Policy可以設置的選項:
- 設置允許的訪問源
- 設置允許的HTTP methods
- 設置允許的請求頭(request header)
- 設置暴露的響應頭(response header)
- 跨不同源請求的證書(Credentials)
- 設置過期時間
AddPolicy 在StartUp.ConfigureServices方法中調用;對於一些選項,先閱讀一下,CORS是怎么工作的,可能會有幫助
設置允許的源(Origins)
AllowAnyOrigin :允許CORS請求從任何源來訪問,這是不安全的
注意:指定AllowAnyOrigin 和AllowCredentials 是一種不安全的配置,可能會導致 跨站請求偽造(cross-site request forgery:CSRF)。
當應用使用這兩個配置時,CORS服務返回一個無效的CORS響應。
SetIsOriginAllowedToAllowWildcardSubdomains:設置策略的 IsOriginAllowed 屬性,使可以匹配一個配置的帶通配符的域名
options.AddPolicy("AllowSubdomain", builder => { builder.SetIsOriginAllowedToAllowWildcardSubdomains(); });
設置允許的HTTP methods
AllowAnyMethod:
- 允許任何HTTP method
- 影響預檢請求(preflight request)和 Access-Control-Allow-Methods header
設置允許的請求頭(request header)
要允許一個CORS請求中指定的請求頭,可以使用 WithHeaders 來指定。
options.AddPolicy("AllowHeaders", builder => { builder.WithOrigins("http://example.com") .WithHeaders(HeaderNames.ContentType, "x-custom-header"); });
允許所有的請求頭
options.AddPolicy("AllowAllHeaders", builder => { builder.WithOrigins("http://example.com") .AllowAnyHeader(); });
一個CORS中間件策略用 WithHeaders匹配特定的頭,而請求中的頭部(記錄在Access-Control-Request-Headers)需要精確匹配WithHeader中的頭部才可以跨域。
例如:
應用中策略
app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));
請求中的部分數據:
Access-Control-Request-Headers: Cache-Control, Content-Language
CORS中間件會拒絕這個請求,因為Content-Language(HeaderNames.ContentLanguage)沒有在WithHeaders中列出來;
設置暴露的響應頭
默認情況下,瀏覽器不會暴露所有的響應頭給應用。
默認可用的響應頭是:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
如果想讓其他的頭部對應用可用,可以調用 WithExposedHeaders:
options.AddPolicy("ExposeResponseHeaders", builder => { builder.WithOrigins("http://example.com") .WithExposedHeaders("x-custom-header"); });
跨源(cross-origin)請求中的證書(Credentials)
默認情況下,瀏覽器不允許在跨域請求中發送證書。
證書中包含緩存(cookies)和HTTP驗證協議(HTTP authentication schemes)。
要再跨域中發送證書,客戶端(瀏覽器)必須設置 XMLHttpRequest.withCredentials 為 true。
直接使用 XMLHttpRequest
var xhr = new XMLHttpRequest(); xhr.open('get', 'https://www.example.com/api/test'); xhr.withCredentials = true;
使用JQuery
$.ajax({ type: 'get', url: 'https://www.example.com/api/test', xhrFields: { withCredentials: true } });
使用 Fetch API
fetch('https://www.example.com/api/test', { credentials: 'include' });
服務端也需要允許證書。使用AllowCredentials
options.AddPolicy("AllowCredentials", builder => { builder.WithOrigins("http://example.com") .AllowCredentials(); });
包含 Access-Control-Allow-Credentials 頭部的HTTP 響應(HTTP Response) 將告訴瀏覽器:服務器允許跨域請求的證書;
如果瀏覽器發送證書,但是響應沒有包含一個有效的 Access-Control-Allow-Credentials 頭部 , 瀏覽器不會暴露響應給應用,跨域失敗;
允許跨域證書是一個安全風險。
在跨域中,如果 Access-Control-Allow-Credentials 頭部出現了,則意味着 設置為所有的源 (setting origin to " * ")會失效。
參考網址
https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2#cors-policy-options
