I have implemented OWIN token based authentication on my WebApi, I have also enabled CORS by calling app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
我已经在我的WebApi上实现了基于OWIN令牌的身份验证,我还通过调用app.UseCors(microsoft.owin . corsoptions.allowall)来启用CORS。
I can access various unsecured portions of my app from an angularjs web client. I have used this http-interceptor , when I try to access a protected resource, I get my login pop.
我可以从angularjs web客户端访问我的应用程序的各种不安全部分。我使用了这个http-截取程序,当我试图访问一个受保护的资源时,我将获得登录弹出。
Now in order to login I have to call http://mywebapi/token
with form encoded UserName Password and grant_type, see my header signature below (from chrome)
现在,为了登录,我必须调用http://mywebapi/token,使用表单编码的用户名密码和grant_type,请参见下面的标题签名(来自chrome)
Request URL:http://mywebapi/token
Request Headers CAUTION: Provisional headers are shown.
Accept:application/json, text/plain, */*
cache:false
Content-Type:application/x-www-form-urlencoded
Origin:http://127.0.0.1:49408
Referer:http://127.0.0.1:49408/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Form Dataview sourceview URL encoded
grant_type:password
UserName:correctuser
Password:Password
When I use postman to send this request, it comes back fine with the expected accesstoken, however when I try to use angular's $http service, it makes the OPTIONS request (I can see this in Dev tools console) but for some reason I get this error message
当我使用postman发送这个请求时,它会恢复到预期的accesstoken,但是当我尝试使用角的$http服务时,它会做出选项请求(我可以在Dev tools console中看到这个),但是出于某种原因,我得到了这个错误消息。
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:49408' is therefore not allowed access.
NOTE: This only happens for the /token request which is form-url-encoded, for all other json requests the header is added as expected. Can someone please help, I am running out of ideas.
注意:这只发生在/令牌请求上,它是表单url编码的,对于所有其他json请求,header是按预期添加的。有人能帮忙吗?我的主意快没了。
Thanks
谢谢
5 个解决方案
#1
17
I went through the same process and spend (wasted?) the same amount of time as most people, dealing with owin + web api.
我经历了相同的过程,花费了(浪费的?)和大多数人一样的时间,处理owin + web api。
A solution which worked for me was to move
一个对我有效的解决办法是搬家
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
before everything else in the pipe.
在管道里的一切之前。
Here is some code:
这里有一些代码:
OwinStartup
OwinStartup
[assembly: OwinStartup(typeof(MyApp.Web.Startup))]
namespace MyApp.Web
{
using Owin;
using Microsoft.Owin;
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new System.Web.Http.HttpConfiguration();
ConfigureAuth(app, config);
}
}
}
Startup for OAuth
启动对OAuth
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app, System.Web.Http.HttpConfiguration config)
{
// app.UseWelcomePage("/");
// app.UseErrorPage();
// Must be the first to be set otherwise it won't work.
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.CreatePerOwinContext<ApplicationDatabaseContext>(ApplicationDatabaseContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
var OAuthOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new DaufAuthorizationServerProvider(),
RefreshTokenProvider = new SimpleAuthorizationServerProvider(),
};
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseWebApi(WebApiConfig.Register(config, logger));
}
}
Web Api
Web Api
public static class WebApiConfig
{
public static HttpConfiguration Register(System.Web.Http.HttpConfiguration config, ILogger logger)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
// This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
return (config);
}
}
#2
12
So I found the answer but brace yourself 'coz this one's weird!! I read this article on code project which led me to my Owin Authorisation server's GrantResourceOwnerCredentials
method to check for this
所以我找到了答案,但你要振作起来,因为这个很奇怪!我阅读了这篇关于代码项目的文章,这篇文章将我引向Owin授权服务器的GrantResourceOwnerCredentials方法来检查这一点
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.OwinContext.Response.Headers。添加(“Access-Control-Allow-Origin”,新的[]{“*”});
(Mine is a custom Authoris(z)ation server, one I nicked off here)
(我的是一个定制的Authoris(z)认证服务器,我在这里偷了一个)
The shocking thing I found was that it was already there!
让我震惊的是,它已经在那里了!
So I decided to set a break point on that line and what do you know, that line was failing because (...even more shocking) "Access-Control-Allow-Origin" was already in the headers!!
所以我决定在这条线上设置一个断点,你知道吗,这条线失败了,因为。更让人吃惊的)“访问-控制-允许-起源”已经在标题中了!
So I commented that line out and it all worked! But then the caveat, I have no idea how the header got in, so I have no idea if it will be there or not in production so I swapped that line of code with this to check and then add it if it was not already there
所以我把这条线注释掉了,结果都成功了!但需要注意的是,我不知道header是如何进入的,所以我不知道它在生产中会不会出现所以我用这行代码来检查,如果它还没有出现,我就添加它
var header = context.OwinContext.Response.Headers.SingleOrDefault(h => h.Key == "Access-Control-Allow-Origin");
if (header.Equals(default(KeyValuePair<string, string[]>)))
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
}
I hope my labour of love will save a few souls from the excruciating damnation of countless hours of tinkering with nothing to solve this problem. Cheers!
我希望我的爱的劳动能拯救一些灵魂,使他们免于为解决这个问题而花上数不清的时间来修修补补。干杯!
#3
7
For those curious about the answer and the previous answer, it is indeed strongly related the ordering. Whenever you are adding Owin middleware it is important to note: The order of registration is imperative.
对于那些对答案和之前的答案感到好奇的人来说,这确实与排序有很大关系。当您在添加Owin中间件时,需要注意的是:注册的顺序是必须的。
app.useCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
app.useCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
Having this as the first thing in your auth file, basically registers the Cors handler to occur prior to reaching your OAuthServer and Web Api.
在您的auth文件中,首先要做的就是注册Cors处理程序,在到达OAuthServer和Web Api之前进行注册。
Moving it after the OAuth does the opposite, hence the need to add the Access-Control-Allow-Origin header in the GrantResourceOwnerCredentials.
在OAuth之后移动它会产生相反的效果,因此需要在grantresourceowner凭据中添加访问控制允许的源头。
To answer the other question, the reason the header is already there is if you send a CORS request from the browser and the CorsOptions.AllowAll is specified, it adds one for you so by the time it reaches the /token endpoint on the OAuth server it has already added one. (just means that one was found in the http request and you are allowing all origins).
要回答另一个问题,标题已经存在的原因是如果您从浏览器和CorsOptions发送CORS请求。AllowAll被指定为添加了一个,因此当它到达OAuth服务器上的/token端点时,它已经添加了一个。(只是表示在http请求中找到了一个,您允许所有的起源)。
You can verify the behaviours accordingly,
你可以验证这些行为,
In Fiddler, send a new request to your Token endpoint with an Origin header included with an arbitrary value. Put a breakpoint on your OAuth server in the GrantResourceOwnerCredentials and then examine context.Response.Headers, it will now contain the origin you passed in. (Remember, the browser must examine it, fiddler will be happy all day long)
在Fiddler中,向令牌端点发送一个新的请求,其中包含一个包含任意值的源头。在GrantResourceOwnerCredentials中在OAuth服务器上放置一个断点,然后检查context.Response。标题,它将包含您传入的源。(记住,浏览器必须检查它,fiddler会整天都很开心的)
If you then tell CORS not to use CorsOptions.AllowAll and set AllowAnyOrigin to false you will notice that the Origin sent from Fiddler is no longer added to the response headers.
如果你告诉CORS不要使用CorsOptions。AllowAll和将AllowAnyOrigin设置为false,您将注意到来自Fiddler的源不再添加到响应头中。
The browser in turn will deny the CORS request because the origin was not returned - Origin "" not found in Access-Control-Allow-Origin header.
浏览器反过来会拒绝CORS请求,因为原点没有返回-原点“在访问控制允许源的消息头中没有找到。
NOW FOR THE IMPORTANT BIT:
现在来谈谈最重要的一点:
If you set CorsOptions.AllowAll it does exactly what it says it does, allows CORS requests to any method on any middleware that occurs after the CORS registration in the Owin pipeline so make sure that is what you intend to do. IE: If you register CORS first then OAuth and Web API then all your Web API methods will be accessible via CORS if you do not explicitly add code\attributes to prevent it.
如果你设置CorsOptions。允许它做它所说的事情,允许CORS请求到在Owin管道中CORS注册之后发生的任何中间件上的任何方法,所以请确保这是您要做的。IE:如果您先注册CORS,然后注册OAuth和Web API,那么如果您不显式地添加代码\属性来阻止它,您的所有Web API方法都可以通过CORS访问。
If you want to restrict the methods then implement an ICorsPolicyProvider, some portions from http://katanaproject.codeplex.com/(Microsoft.Owin.Cors)
如果您想限制这些方法,那么实现一个ICorsPolicyProvider, http://katanaproject.codeplex.com/(Microsoft.Owin.Cors)
public class MyCorsPolicyProvider : ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(IOwinRequest request)
{
// Grant Nothing.
var policy = new CorsPolicy
{
AllowAnyHeader = false,
AllowAnyMethod = false,
AllowAnyOrigin = false,
SupportsCredentials = false
};
// Now we can get a bit clever: (Awesome, they requested the token endpoint. Setup OAuth options for that.
if (OAuthOptions.TokenEndpointPath.HasValue && OAuthOptions.TokenEndpointPath == request.Path)
{
// Hypothetical scenario, tokens can only be obtained using CORS when the Origin is http://localhost
policy.AllowAnyHeader = true;
policy.AllowAnyMethod = true;
policy.AllowAnyOrigin = false;
policy.SupportsCredentials = true;
policy.Origins.Add("http://localhost");
return Task.FromResult(policy);
}
// No token?, must already have one.... so this must be a WebApi request then.
// From here we could check where the request is going, do some other fun stuff etc... etc...
// Alternatively, do nothing, set config.EnableCors() in WebApi, then apply the EnableCors() attribute on your methods to allow it through.
return null; }
}
The return null; tells Owin to continue to the next middleware and to allow the request through but with no policy thus NO CORS!, allowing you to set appropriate CORS attributes in WebAPI
返回null;告诉Owin继续到下一个中间件,允许请求通过但没有策略,因此没有CORS!,允许您在WebAPI中设置适当的CORS属性
Now the really important bit, DO NOT add the Access-Control-Allow-Origins header to your response if it is not there unless that is really what you intend as depending on your middleware registration order it will open all the doors for CORS requests unless you explicitly block them elsewhere or remove the header and basically will cause you lots of issues when you try and use CORS with WebApi and want to restrict it.
现在很重要的一点,不要将Access-Control-Allow-Origins头添加到你的反应,如果没有,除非是真正想根据您的中间件注册秩序,它将打开所有的门歌珥请求,除非你显式地阻止他们在其他地方或删除页眉和基本上会导致你很多问题当你试着使用歌珥WebApi和想要限制它。
To block them elsewhere you could add a CorsPolicyProvider (System.Web.Http) for WebApi then set a Context variable in Owin which you can read once the request hits WebApi.
要在其他地方阻止它们,您可以为WebApi添加一个CorsPolicyProvider (System.Web.Http),然后在Owin中设置一个上下文变量,当请求到达WebApi时,您可以在其中读取。
public class WebApiCorsPolicyProvider : System.Web.Http.Cors.ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var policy = new CorsPolicy
{
AllowAnyHeader = false,
AllowAnyMethod = false,
AllowAnyOrigin = false,
SupportsCredentials = false
};
// The benefit of being at this point in the pipeline is we have been authenticated\authorized so can check all our claims for CORS purposes too if needed and set errors etc...
// In an Owin pipeline?
var owinContext = request.GetOwinContext();
if (owinContext != null)
{
// We have an owin pipeline, we can get owin parameters and other things here.
}
else
{
// Write your code here to determine the right CORS options. Non Owin pipeline variant.
}
return Task.FromResult(policy);
}
}
And finally, one other benefit of propagating downwards to a WebApi CORS policy provider is that at that point Authorization will have taken place so you can then apply additional Origin filters at that stage in the CORS policy provider.
最后,向下传播到WebApi CORS策略提供程序的另一个好处是,此时将进行授权,这样您就可以在CORS策略提供程序的那个阶段应用额外的源过滤器。
#4
2
In my opinion it is related to ordering of your statements though I did not investigated further. I faced the same issue and tried all combinations and eventually following worked for me.
我认为这与你的陈述的顺序有关,虽然我没有进一步调查。我遇到了同样的问题,尝试了所有的组合,最终跟随了我。
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
I was following Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
我使用ASP进行基于令牌的身份验证。NET Web API 2、Owin和Identity
#5
1
This is another version of the code for the Obi Onuorah's response
这是Obi Onuorah响应代码的另一个版本
string corsHeader = "Access-Control-Allow-Origin";
if (!context.Response.Headers.ContainsKey(corsHeader))
{
context.Response.Headers.Add(corsHeader, new[] { "*" });
}
#1
17
I went through the same process and spend (wasted?) the same amount of time as most people, dealing with owin + web api.
我经历了相同的过程,花费了(浪费的?)和大多数人一样的时间,处理owin + web api。
A solution which worked for me was to move
一个对我有效的解决办法是搬家
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
before everything else in the pipe.
在管道里的一切之前。
Here is some code:
这里有一些代码:
OwinStartup
OwinStartup
[assembly: OwinStartup(typeof(MyApp.Web.Startup))]
namespace MyApp.Web
{
using Owin;
using Microsoft.Owin;
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new System.Web.Http.HttpConfiguration();
ConfigureAuth(app, config);
}
}
}
Startup for OAuth
启动对OAuth
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app, System.Web.Http.HttpConfiguration config)
{
// app.UseWelcomePage("/");
// app.UseErrorPage();
// Must be the first to be set otherwise it won't work.
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.CreatePerOwinContext<ApplicationDatabaseContext>(ApplicationDatabaseContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
var OAuthOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new DaufAuthorizationServerProvider(),
RefreshTokenProvider = new SimpleAuthorizationServerProvider(),
};
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseWebApi(WebApiConfig.Register(config, logger));
}
}
Web Api
Web Api
public static class WebApiConfig
{
public static HttpConfiguration Register(System.Web.Http.HttpConfiguration config, ILogger logger)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
// This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
return (config);
}
}
#2
12
So I found the answer but brace yourself 'coz this one's weird!! I read this article on code project which led me to my Owin Authorisation server's GrantResourceOwnerCredentials
method to check for this
所以我找到了答案,但你要振作起来,因为这个很奇怪!我阅读了这篇关于代码项目的文章,这篇文章将我引向Owin授权服务器的GrantResourceOwnerCredentials方法来检查这一点
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.OwinContext.Response.Headers。添加(“Access-Control-Allow-Origin”,新的[]{“*”});
(Mine is a custom Authoris(z)ation server, one I nicked off here)
(我的是一个定制的Authoris(z)认证服务器,我在这里偷了一个)
The shocking thing I found was that it was already there!
让我震惊的是,它已经在那里了!
So I decided to set a break point on that line and what do you know, that line was failing because (...even more shocking) "Access-Control-Allow-Origin" was already in the headers!!
所以我决定在这条线上设置一个断点,你知道吗,这条线失败了,因为。更让人吃惊的)“访问-控制-允许-起源”已经在标题中了!
So I commented that line out and it all worked! But then the caveat, I have no idea how the header got in, so I have no idea if it will be there or not in production so I swapped that line of code with this to check and then add it if it was not already there
所以我把这条线注释掉了,结果都成功了!但需要注意的是,我不知道header是如何进入的,所以我不知道它在生产中会不会出现所以我用这行代码来检查,如果它还没有出现,我就添加它
var header = context.OwinContext.Response.Headers.SingleOrDefault(h => h.Key == "Access-Control-Allow-Origin");
if (header.Equals(default(KeyValuePair<string, string[]>)))
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
}
I hope my labour of love will save a few souls from the excruciating damnation of countless hours of tinkering with nothing to solve this problem. Cheers!
我希望我的爱的劳动能拯救一些灵魂,使他们免于为解决这个问题而花上数不清的时间来修修补补。干杯!
#3
7
For those curious about the answer and the previous answer, it is indeed strongly related the ordering. Whenever you are adding Owin middleware it is important to note: The order of registration is imperative.
对于那些对答案和之前的答案感到好奇的人来说,这确实与排序有很大关系。当您在添加Owin中间件时,需要注意的是:注册的顺序是必须的。
app.useCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
app.useCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
Having this as the first thing in your auth file, basically registers the Cors handler to occur prior to reaching your OAuthServer and Web Api.
在您的auth文件中,首先要做的就是注册Cors处理程序,在到达OAuthServer和Web Api之前进行注册。
Moving it after the OAuth does the opposite, hence the need to add the Access-Control-Allow-Origin header in the GrantResourceOwnerCredentials.
在OAuth之后移动它会产生相反的效果,因此需要在grantresourceowner凭据中添加访问控制允许的源头。
To answer the other question, the reason the header is already there is if you send a CORS request from the browser and the CorsOptions.AllowAll is specified, it adds one for you so by the time it reaches the /token endpoint on the OAuth server it has already added one. (just means that one was found in the http request and you are allowing all origins).
要回答另一个问题,标题已经存在的原因是如果您从浏览器和CorsOptions发送CORS请求。AllowAll被指定为添加了一个,因此当它到达OAuth服务器上的/token端点时,它已经添加了一个。(只是表示在http请求中找到了一个,您允许所有的起源)。
You can verify the behaviours accordingly,
你可以验证这些行为,
In Fiddler, send a new request to your Token endpoint with an Origin header included with an arbitrary value. Put a breakpoint on your OAuth server in the GrantResourceOwnerCredentials and then examine context.Response.Headers, it will now contain the origin you passed in. (Remember, the browser must examine it, fiddler will be happy all day long)
在Fiddler中,向令牌端点发送一个新的请求,其中包含一个包含任意值的源头。在GrantResourceOwnerCredentials中在OAuth服务器上放置一个断点,然后检查context.Response。标题,它将包含您传入的源。(记住,浏览器必须检查它,fiddler会整天都很开心的)
If you then tell CORS not to use CorsOptions.AllowAll and set AllowAnyOrigin to false you will notice that the Origin sent from Fiddler is no longer added to the response headers.
如果你告诉CORS不要使用CorsOptions。AllowAll和将AllowAnyOrigin设置为false,您将注意到来自Fiddler的源不再添加到响应头中。
The browser in turn will deny the CORS request because the origin was not returned - Origin "" not found in Access-Control-Allow-Origin header.
浏览器反过来会拒绝CORS请求,因为原点没有返回-原点“在访问控制允许源的消息头中没有找到。
NOW FOR THE IMPORTANT BIT:
现在来谈谈最重要的一点:
If you set CorsOptions.AllowAll it does exactly what it says it does, allows CORS requests to any method on any middleware that occurs after the CORS registration in the Owin pipeline so make sure that is what you intend to do. IE: If you register CORS first then OAuth and Web API then all your Web API methods will be accessible via CORS if you do not explicitly add code\attributes to prevent it.
如果你设置CorsOptions。允许它做它所说的事情,允许CORS请求到在Owin管道中CORS注册之后发生的任何中间件上的任何方法,所以请确保这是您要做的。IE:如果您先注册CORS,然后注册OAuth和Web API,那么如果您不显式地添加代码\属性来阻止它,您的所有Web API方法都可以通过CORS访问。
If you want to restrict the methods then implement an ICorsPolicyProvider, some portions from http://katanaproject.codeplex.com/(Microsoft.Owin.Cors)
如果您想限制这些方法,那么实现一个ICorsPolicyProvider, http://katanaproject.codeplex.com/(Microsoft.Owin.Cors)
public class MyCorsPolicyProvider : ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(IOwinRequest request)
{
// Grant Nothing.
var policy = new CorsPolicy
{
AllowAnyHeader = false,
AllowAnyMethod = false,
AllowAnyOrigin = false,
SupportsCredentials = false
};
// Now we can get a bit clever: (Awesome, they requested the token endpoint. Setup OAuth options for that.
if (OAuthOptions.TokenEndpointPath.HasValue && OAuthOptions.TokenEndpointPath == request.Path)
{
// Hypothetical scenario, tokens can only be obtained using CORS when the Origin is http://localhost
policy.AllowAnyHeader = true;
policy.AllowAnyMethod = true;
policy.AllowAnyOrigin = false;
policy.SupportsCredentials = true;
policy.Origins.Add("http://localhost");
return Task.FromResult(policy);
}
// No token?, must already have one.... so this must be a WebApi request then.
// From here we could check where the request is going, do some other fun stuff etc... etc...
// Alternatively, do nothing, set config.EnableCors() in WebApi, then apply the EnableCors() attribute on your methods to allow it through.
return null; }
}
The return null; tells Owin to continue to the next middleware and to allow the request through but with no policy thus NO CORS!, allowing you to set appropriate CORS attributes in WebAPI
返回null;告诉Owin继续到下一个中间件,允许请求通过但没有策略,因此没有CORS!,允许您在WebAPI中设置适当的CORS属性
Now the really important bit, DO NOT add the Access-Control-Allow-Origins header to your response if it is not there unless that is really what you intend as depending on your middleware registration order it will open all the doors for CORS requests unless you explicitly block them elsewhere or remove the header and basically will cause you lots of issues when you try and use CORS with WebApi and want to restrict it.
现在很重要的一点,不要将Access-Control-Allow-Origins头添加到你的反应,如果没有,除非是真正想根据您的中间件注册秩序,它将打开所有的门歌珥请求,除非你显式地阻止他们在其他地方或删除页眉和基本上会导致你很多问题当你试着使用歌珥WebApi和想要限制它。
To block them elsewhere you could add a CorsPolicyProvider (System.Web.Http) for WebApi then set a Context variable in Owin which you can read once the request hits WebApi.
要在其他地方阻止它们,您可以为WebApi添加一个CorsPolicyProvider (System.Web.Http),然后在Owin中设置一个上下文变量,当请求到达WebApi时,您可以在其中读取。
public class WebApiCorsPolicyProvider : System.Web.Http.Cors.ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var policy = new CorsPolicy
{
AllowAnyHeader = false,
AllowAnyMethod = false,
AllowAnyOrigin = false,
SupportsCredentials = false
};
// The benefit of being at this point in the pipeline is we have been authenticated\authorized so can check all our claims for CORS purposes too if needed and set errors etc...
// In an Owin pipeline?
var owinContext = request.GetOwinContext();
if (owinContext != null)
{
// We have an owin pipeline, we can get owin parameters and other things here.
}
else
{
// Write your code here to determine the right CORS options. Non Owin pipeline variant.
}
return Task.FromResult(policy);
}
}
And finally, one other benefit of propagating downwards to a WebApi CORS policy provider is that at that point Authorization will have taken place so you can then apply additional Origin filters at that stage in the CORS policy provider.
最后,向下传播到WebApi CORS策略提供程序的另一个好处是,此时将进行授权,这样您就可以在CORS策略提供程序的那个阶段应用额外的源过滤器。
#4
2
In my opinion it is related to ordering of your statements though I did not investigated further. I faced the same issue and tried all combinations and eventually following worked for me.
我认为这与你的陈述的顺序有关,虽然我没有进一步调查。我遇到了同样的问题,尝试了所有的组合,最终跟随了我。
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
I was following Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
我使用ASP进行基于令牌的身份验证。NET Web API 2、Owin和Identity
#5
1
This is another version of the code for the Obi Onuorah's response
这是Obi Onuorah响应代码的另一个版本
string corsHeader = "Access-Control-Allow-Origin";
if (!context.Response.Headers.ContainsKey(corsHeader))
{
context.Response.Headers.Add(corsHeader, new[] { "*" });
}