4

(我很抱歉在这里和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();
4

4 回答 4

8

为了让 CORS 与 OWIN 令牌端点很好地配合,我必须安装Microsoft.Owin.CorsNuget 包,然后添加以下代码行:

启动.Auth.cs

using Microsoft.Owin.Cors;
// ...

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // ...
        app.UseCors(CorsOptions.AllowAll);

添加包并在代码中配置 CORS 后,它工作得很好。

于 2014-03-26T18:33:40.643 回答
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));
于 2014-01-23T07:48:25.313 回答
1

一个合适的答案已经被接受,但是当我遇到这个问题时,我发现我必须在 Providers > ApplicaitonOAuthProvider 类中添加一行。当我尝试从 Azure 中的远程网站访问 WebApi 时。

在此处输入图像描述

于 2014-12-30T16:57:23.670 回答
1

以上没有解决我 /token 未设置允许标头的问题。我在以下位置找到了解决此问题的方法:

ASP.NET WEB API 2 OWIN 身份验证不受支持的 grant_Type

Aparently Token 在 Owin Request 上下文中运行,并且与其余部分分开......

于 2014-03-13T09:55:32.223 回答