在 Asp.net Web API 中处理 CORS 预检
Handling CORS Preflight in Asp.net Web API
我的架构中有三个应用程序。
它们在同一台服务器上,但具有不同的端口号。
A - Token Application (port 4444) - Asp.net WebApi
B - API Application (port 3333) - Asp.net WebApi
C - UI Application (port 2222) - AngularJS App.
申请流程如下
1- UI 项目从令牌应用程序获取令牌(它需要 Windows 身份验证。)
例如:awxrsdsaWeffs12da
2- UI 应用程序将此令牌放入名为 "accessToken"
的自定义 header
例如:访问令牌:awxrsdsaWeffs12da
3- UI 应用程序向 API 应用程序发送请求
例如:http:myaddress:3333/api/TheRestServiceHere
UI 应用程序出现 401 错误。
其中发送 OPTIONS 方法。 (我猜是预检问题)
在我的网络 api 项目中,我启用了如下所示的 Cors。
public static void Register(HttpConfiguration config)
{
....
//CORS
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
....
}
配置
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//CORS
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
json.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
json.SerializerSettings.Formatting = Formatting.None;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
}
所以我正在寻找调用 API 应用程序 (B) 控制器的解决方案
并获得 200 :)
此致
我的一个朋友使用 OPTIONSVerbHandler 解决了这个问题。
当UI应用程序想要使用GET方法时,浏览器发送
OPTION方法先到服务器(Preflight)。然后,如果预检请求正常,它会发送 GET 请求。
出于 CORS 测试目的,我们使用以下代码发送 GET 方法。
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$( document ).ready(function() {
var adress = "http://10.10.27.36:3434/backend/api/role";
$.ajaxSetup({
headers: {
'Content-Type': 'application/json',
'accessToken': 'some value',
'Origin' : ''
}
});
$.ajax({
type: "GET",
url: adress,
dataType: "json"
});
});
</script></head><body></body></html>
要处理在 GET 之前由浏览器发送的 OPTION 方法,您应该进行以下设置。
1- 网络配置
<system.webServer>
<handlers>
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" />
</handlers>
</system.webServer>
2- 使用以下设置添加 OPTIONSVerbHandler
点击请求限制
3- 我们的 Header 设置有 accessToken,如您所见,这是自定义的
我通过创建一个响应使用 OPTIONS 动词的请求的模块在我正在处理的应用程序中解决了这个问题。您可能应该稍微修改它以包括应用程序请求的动词和内容类型。就我而言,我决定将所有内容 post 设为 JSON(这需要进行飞行前检查)。模块如下:
public class OptionsModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, args) =>
{
var app = (HttpApplication) sender;
if (app.Request.HttpMethod == "OPTIONS")
{
app.Response.StatusCode = 200;
app.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
app.Response.AddHeader("Access-Control-Allow-Origin", APISettings.ApplicationOrigin);
app.Response.AddHeader("Access-Control-Allow-Credentials", "true");
app.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
app.Response.AddHeader("Content-Type", "application/json");
app.Response.End();
}
};
}
public void Dispose()
{
}
}
然后你需要在你的web.config中注册它:
<system.webServer>
<modules>
<add name="HandleOptions" type="namespace.OptionsModule" />
</modules>
</system.webServer>
您可能想要做的另一件事是明确指定允许的来源。 Chrome 不喜欢那里有通配符。
对于 Azure 环境
您需要允许来自门户的来源。
我的架构中有三个应用程序。
它们在同一台服务器上,但具有不同的端口号。
A - Token Application (port 4444) - Asp.net WebApi
B - API Application (port 3333) - Asp.net WebApi
C - UI Application (port 2222) - AngularJS App.
申请流程如下
1- UI 项目从令牌应用程序获取令牌(它需要 Windows 身份验证。)
例如:awxrsdsaWeffs12da
2- UI 应用程序将此令牌放入名为 "accessToken"
的自定义 header例如:访问令牌:awxrsdsaWeffs12da
3- UI 应用程序向 API 应用程序发送请求
例如:http:myaddress:3333/api/TheRestServiceHere
UI 应用程序出现 401 错误。 其中发送 OPTIONS 方法。 (我猜是预检问题)
在我的网络 api 项目中,我启用了如下所示的 Cors。
public static void Register(HttpConfiguration config)
{
....
//CORS
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
....
}
配置
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//CORS
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
json.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
json.SerializerSettings.Formatting = Formatting.None;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
}
所以我正在寻找调用 API 应用程序 (B) 控制器的解决方案 并获得 200 :)
此致
我的一个朋友使用 OPTIONSVerbHandler 解决了这个问题。
当UI应用程序想要使用GET方法时,浏览器发送 OPTION方法先到服务器(Preflight)。然后,如果预检请求正常,它会发送 GET 请求。
出于 CORS 测试目的,我们使用以下代码发送 GET 方法。
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$( document ).ready(function() {
var adress = "http://10.10.27.36:3434/backend/api/role";
$.ajaxSetup({
headers: {
'Content-Type': 'application/json',
'accessToken': 'some value',
'Origin' : ''
}
});
$.ajax({
type: "GET",
url: adress,
dataType: "json"
});
});
</script></head><body></body></html>
要处理在 GET 之前由浏览器发送的 OPTION 方法,您应该进行以下设置。
1- 网络配置
<system.webServer>
<handlers>
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" />
</handlers>
</system.webServer>
2- 使用以下设置添加 OPTIONSVerbHandler
点击请求限制
3- 我们的 Header 设置有 accessToken,如您所见,这是自定义的
我通过创建一个响应使用 OPTIONS 动词的请求的模块在我正在处理的应用程序中解决了这个问题。您可能应该稍微修改它以包括应用程序请求的动词和内容类型。就我而言,我决定将所有内容 post 设为 JSON(这需要进行飞行前检查)。模块如下:
public class OptionsModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, args) =>
{
var app = (HttpApplication) sender;
if (app.Request.HttpMethod == "OPTIONS")
{
app.Response.StatusCode = 200;
app.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
app.Response.AddHeader("Access-Control-Allow-Origin", APISettings.ApplicationOrigin);
app.Response.AddHeader("Access-Control-Allow-Credentials", "true");
app.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
app.Response.AddHeader("Content-Type", "application/json");
app.Response.End();
}
};
}
public void Dispose()
{
}
}
然后你需要在你的web.config中注册它:
<system.webServer>
<modules>
<add name="HandleOptions" type="namespace.OptionsModule" />
</modules>
</system.webServer>
您可能想要做的另一件事是明确指定允许的来源。 Chrome 不喜欢那里有通配符。
对于 Azure 环境
您需要允许来自门户的来源。