(我很抱歉在这里和github发布此问题,但我真的需要帮助...)
在使用Thinktecture.IdentityModel.45进行身份验证时,我无法启用CORS(System.Web.Http.Cors)。
我的令牌端点有问题,我正在使用默认的“/ token”。
当调用/ token(来自javascript客户端)时,浏览器发出2个调用,“OPTION”调用和“/ token”资源的“GET”调用。我正在使用一个简单的PolicyProviderFactory来检查请求是否获得正确的CORS策略并且它只返回
new EnableCorsAttribute("*", "*", "*");
第一个OPTION调用有效,GetCorsPolicyProvider被命中。另一个调用有效,但GetCorsPolicyProvider没有被命中,结果是服务器返回200 OK,包含所有正确的标题等,但内容响应为空。
我需要在路由配置中为令牌资源添加以下内容,否则我会得到“未找到”。
config.Routes.MapHttpRoute(
name: "SecurityToken",
routeTemplate: "api/token");
在所有其他请求中,OPTIONS和GET都会调用CORS策略提供程序,一切正常。我调试了thinktecture.identitymodel和相应的响应,返回正确的令牌。
/ token资源的GET方法不会调用CORS策略提供程序..但为什么? CorsMessageHandler已加载但从未被调用。如何判断请求是否会触发CORS / CorsMessageHandler?
诊断跟踪:
w3wp.exe Information: 0 : Request, Method=OPTIONS, Url=https://localhost/myapp/api/token, Message='https://localhost/myapp/api/token'
w3wp.exe Information: 0 : Message='CorsPolicyProvider selected: 'System.Web.Http.Cors.EnableCorsAttribute'', Operation=MyPolicyProviderFactory.GetCorsPolicyProvider
w3wp.exe Information: 0 : Message='CorsPolicy selected: 'AllowAnyHeader: True, AllowAnyMethod: True, AllowAnyOrigin: True, PreflightMaxAge: null, SupportsCredentials: True, Origins: {}, Methods: {}, Headers: {}, ExposedHeaders: {}'', Operation=EnableCorsAttribute.GetCorsPolicyAsync
w3wp.exe Information: 0 : Message='CorsResult returned: 'IsValid: True, AllowCredentials: True, PreflightMaxAge: null, AllowOrigin: https://localhost:4433, AllowExposedHeaders: {}, AllowHeaders: {access-key,authorization}, AllowMethods: {GET}, ErrorMessages: {}'', Operation=CorsEngine.EvaluatePolicy
w3wp.exe Information: 0 : Operation=CorsMessageHandler.SendAsync, Status=200 (OK)
w3wp.exe Information: 0 : Operation=AuthenticationHandler.SendAsync, Status=200 (OK)
w3wp.exe Information: 0 : Response, Status=200 (OK), Method=OPTIONS, Url=https://localhost/myapp/api/token, Message='Content-type='none', content-length=unknown'
w3wp.exe Information: 0 : Request, Method=GET, Url=https://localhost/myapp/api/token, Message='https://localhost/myapp/api/token'
w3wp.exe Information: 0 : Operation=AuthenticationHandler.SendAsync, Status=200 (OK)
w3wp.exe Information: 0 : Response, Status=200 (OK), Method=GET, Url=https://localhost/myapp/api/token, Message='Content-type='application/json; charset=utf-8', content-length=851'
身份验证配置如下所示:
var authentication = new AuthenticationConfiguration
{
ClaimsAuthenticationManager = new ClaimsTransformer(),
RequireSsl = false,
EnableSessionToken = true,
SendWwwAuthenticateResponseHeaders = true
};
var accessKeyHandler = new SimpleSecurityTokenHandler(
"accessKey",
AccessKey.Validate);
authentication.AddAccessKey(
accessKeyHandler,
AuthenticationOptions.ForHeader("access-key"));
authentication.AddBasicAuthentication(UserCredentials.Validate, retainPassword: true);
PassiveSessionConfiguration.ConfigureMackineKeyProtectionForSessionTokens();
答案 0 :(得分:8)
为了让CORS与OWIN Token端点很好地配合,我必须安装Microsoft.Owin.Cors
Nuget包然后添加这行代码:
<强> Startup.Auth.cs 强>
using Microsoft.Owin.Cors;
// ...
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// ...
app.UseCors(CorsOptions.AllowAll);
添加软件包并在代码中配置CORS后,它工作得很好。
答案 1 :(得分:2)
问题是需要在AuthenticationHandler之前添加CorsHandler。但我这样做了:
config.EnableCors();
// ...
config.MessageHandlers.Add(new AuthenticationHandler(authentication));
但这会使CorsHandler在config.MessageHandlers中的AuthenticationHandler之后。因为.EnableCors通过LazyInitializer添加处理程序。
为了解决这个问题,我做了:
config.EnableCors();
config.EnsureInitialized(); // this will add the handler to the .MessageHandlers
config.MessageHandlers.Add(new AuthenticationHandler(authentication));
事实证明这是不稳定的..稳定的解决方案是“手动”添加CorsMessageHandler:
AttributeBasedPolicyProviderFactory corsPolicyProviderFactory = new AttributeBasedPolicyProviderFactory
{
DefaultPolicyProvider = corsAttribute
};
config.SetCorsPolicyProviderFactory(corsPolicyProviderFactory);
config.MessageHandlers.Add(new CorsMessageHandler(config));
答案 2 :(得分:1)
以上并没有解决我的问题,/ token没有设置Allow headers。 我找到了解决这个问题的方法:
ASP.NET WEB API 2 OWIN Authentication unsuported grant_Type
Aparently Token在Owin Request上下文中运行,并与其余部分分开......
答案 3 :(得分:1)
已经接受了一个合适的答案但是当我遇到这个问题时,我发现我必须向Providers添加一行&gt; ApplicaitonOAuthProvider类。当我试图从Azure中的远程网站访问WebApi时。