2014-10-28 91 views
9

OPTIONS我使用令牌認證基於本文的小項目請求無效:http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/OWIN令牌認證400從瀏覽器

一切似乎除了一兩件事,做工精細:OWIN基於令牌的認證不允許OPTIONS請求on/token端點。 Web API返回400錯誤請求,並且整個瀏覽器應用程序停止發送POST請求以獲取令牌。

我已經在示例項目中啓用了應用程序中的所有CORS。下面一些代碼,可能是相關的:

public class Startup 
    { 
     public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } 

     public void Configuration(IAppBuilder app) 
     { 
      AreaRegistration.RegisterAllAreas(); 
      UnityConfig.RegisterComponents(); 
      GlobalConfiguration.Configure(WebApiConfig.Register); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      HttpConfiguration config = new HttpConfiguration(); 

      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

      ConfigureOAuth(app); 

      WebApiConfig.Register(config); 

      app.UseWebApi(config); 

      Database.SetInitializer(new ApplicationContext.Initializer()); 
     } 

     public void ConfigureOAuth(IAppBuilder app) 
     { 
      //use a cookie to temporarily store information about a user logging in with a third party login provider 
      app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie); 
      OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); 

      OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new PathString("/token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60), 
       Provider = new SimpleAuthorizationServerProvider(), 
       RefreshTokenProvider = new SimpleRefreshTokenProvider() 
      }; 

      // Token Generation 
      app.UseOAuthAuthorizationServer(OAuthServerOptions); 
      app.UseOAuthBearerAuthentication(OAuthBearerOptions); 
     } 
    } 

下面是我的javascript登錄功能(我爲此使用angularjs)

var _login = function (loginData) { 

     var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password; 

     data = data + "&client_id=" + ngAuthSettings.clientId; 

     var deferred = $q.defer(); 

     $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) { 

     localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true }); 
     _authentication.isAuth = true; 
     _authentication.userName = loginData.userName; 
     _authentication.useRefreshTokens = loginData.useRefreshTokens; 

     deferred.resolve(response); 

     }).error(function (err, status) { 
      _logOut(); 
      deferred.reject(err); 
     }); 

     return deferred.promise; 
    }; 

    var _logOut = function() { 

     localStorageService.remove('authorizationData'); 

     _authentication.isAuth = false; 
     _authentication.userName = ""; 
     _authentication.useRefreshTokens = false; 

    }; 

回答

-3

解決它。問題不是通過OPTIONS請求頭髮送訪問控制請求方法

+2

正想回答你,但你解決它,很高興我的教程和代碼示例是有用的:) – 2014-10-28 21:40:43

+2

同樣的問題在這裏。而且我還沒有理解如何解決這個問題。 – otaviosoares 2014-11-18 14:13:27

+2

我會一直很好,如果你闡述了你是如何解決這個問題..我解決了它使用@knr – Aziz 2015-07-31 15:47:57

31

我今天在這個問題上已經失去了一些時間。最後我想我已經找到了解決方案。您OAuthAuthorizationServerProvider內

覆蓋方法:

public override Task MatchEndpoint(OAuthMatchEndpointContext context) 
{ 
    if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS") 
    { 
     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 
     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization" }); 
     context.RequestCompleted(); 
     return Task.FromResult(0); 
    } 

    return base.MatchEndpoint(context); 
} 

這似乎做三件所需的東西:

  • 力auth服務器響應選項200(OK)HTTP狀態請求,
  • 通過設置允許請求來自任何地方Access-Control-Allow-Origin
  • 允許Authorization頭設置在subseq通過設置的向上請求Access-Control-Allow-Headers

經過這些步驟後,角度最終在使用OPTIONS方法請求令牌端點時表現正確。返回OK狀態,它重複使用POST方法獲取完整令牌數據的請求。

+0

感謝@knr,您的解決方案對我來說工作得很好。 我還在響應中添加了標頭「允許」,給出了針對資源承認的HTTP動詞列表: context.OwinContext.Response.Headers.Add(「Allow」,new [] {「GET,POST,PUT ,DELETE,HEAD「}); – 2015-07-08 08:48:06

+0

謝謝@knr,你的解決方案也適用於我。 – 2015-08-14 13:45:46

-4

這應該做的伎倆:

app.UseCors(CorsOptions.AllowAll); 
+2

請稍作解釋,以便其他用戶可以瞭解問題的原因以及解決方案的工作原理。謝謝 :) – 2015-06-23 16:36:18