我有一个在我们的Intranet中使用的Web API应用程序。我们还使用Windows身份验证来定义谁可以在Intranet中访问这些Web API的限制。
另外,我们有一个angularJS应用程序。它使用WEB API应用程序。这些应用程序的领域是不同的。因此我们使用了CORS。
为了启用CORS,我们使用了Microsoft CORS Nuget包。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var cors = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors);
}
}
我有两个WEB API(GET和POST)。加载我的UI时,将调用GET API。当用户单击“保存”按钮时,将调用POST API。
[RoutePrefix("api/call")]
[Authorize]
public class CallController : TecApiController
{
[HttpGet]
[Route("GetInfo")]
public IHttpActionResult GetCallInfo(int Id)
{
//return Model
}
[HttpPost]
[Route("saveInfo")]
public IHttpActionResult SetUncompleteCallToDismissed([FromBody] Model model)
{
// Save Model
}
}
我用于调用API的AngularJS服务如下所示
$http.get(apiEndPoint + 'GetInfo/' + Id, { withCredentials: true })
.then(function (response) { return response.data; }, handleError);
$http.post(apiEndPoint + 'saveInfo/', model, { withCredentials: true })
.then(function (response) { return response.data; }, handleError);
我的问题是GET方法运行良好。但是当我点击帖子时,我的浏览器控制台出现了以下错误:
XMLHttpRequest无法加载 http://localhost:35059/api/call/saveInfo。回应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许来源“http://localhost:3000” 访问。响应的HTTP状态代码为401。
这里发生的最有线的事情是当我运行Fiddler来调试请求时,一切都变好了。
请告诉我如何解决它。
答案 0 :(得分:2)
好的,对于有同样问题的人。
启用Windows身份验证时,无法使用*
作为原点。
你必须指定原点。
就我而言,在 WebApiConfig.cs
中定义以下部分 var cors = new EnableCorsAttribute("http://IP:PORT", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors);
最重要的部分是你必须处理预检请求。我选择Global.asax.cs(不是最好的选择,但是最明星的前进)来处理这类请求
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Headers.Add("Access-Control-Allow-Origin", "http://IP:PORT");
Response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
Response.Headers.Add("Access-Control-Allow-Credentials", "true");
Response.Headers.Add("Access-Control-Max-Age", "1728000");
Response.End();
}
}
Response.Headers.Add("Access-Control-Allow-Credentials", "true");
如果你的网络API中有Windows身份验证,那么这部分就是mandetory。
最后一件事(以及最烦人的事情)你不能在你的ApiController中使用 Route
和RoutePrefix
属性。 您必须在WebApiConfig.cs
中定义所有路由,因为路由属性会更改请求的标头并删除Windows身份验证和CORS所需的所有标头。
config.Routes.MapHttpRoute(
name: "GetInfo",
routeTemplate: "api/call/getinfo",
defaults: new { action = "GetCallInfo", controller = "Call" }
);