Asp.net

WebAPI 和 SignalR Web 應用程序 - 身份驗證和授權

  • November 11, 2016

我有一個WebAPI解決方案並且我使用token authentication,所以流程如下:

  • 使用者嘗試使用usernameand登錄password
  • 如果憑據正確,他將獲得一個令牌,以便在以下請求中使用(放置在AJAX請求的標頭中)。

現在SignalR開始發揮作用。由於它使用WebSockets,因此您無法傳遞標頭。在尋找解決方案時,我遇到了以下問題:

  1. 實際上將標頭傳遞給 SignalR- 而不是選項,因為它強制SignalR使用longPolling.

$.signalR.ajaxDefaults.headers = { Authorization: "Bearer " + token };

  1. token將用於驗證WebAPI呼叫的相同傳遞為query string/ 或將其儲存在 cookie 中SignalR,然後創建一個提供程序,以某種方式將令牌解包並擴展為身份。我關注了這篇博文,但我似乎遺漏了一些東西。
  2. 再次將令牌作為/ 或 cookie傳遞query string,但這次創建一個自定義集線器或方法。 又是一篇關於此的博文。此解決方案的問題在於令牌的方法。Authorize Attribute``Authorize SignalR``Unprotect
  3. 最後也是最簡單的解決方案是也啟用cookie authentication、繼續使用bearer token authentication呼叫WebAPI並讓OWIN Middleware集線器上的呼叫授權。(這個解決方案實際上有效)。

現在,問題是使用WebAPI應用程序的預設模板Individual User Accounts(因此使用令牌身份驗證),每當我向它發送AJAX請求時,API它也會發送 cookie。

public partial class Startup
   {
       public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

       public static string PublicClientId { get; private set; }

       // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
       public void ConfigureAuth(IAppBuilder app)
       {
           // Configure the db context and user manager to use a single instance per request
           app.CreatePerOwinContext(ApplicationDbContext.Create);
           app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

           app.UseCookieAuthentication(new CookieAuthenticationOptions());


           PublicClientId = "self";
           OAuthOptions = new OAuthAuthorizationServerOptions
           {
               TokenEndpointPath = new PathString("/Token"),
               Provider = new ApplicationOAuthProvider(PublicClientId),
               AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
               AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
               AllowInsecureHttp = true
           };

           app.UseOAuthBearerTokens(OAuthOptions);

       }
   }



public static class WebApiConfig
{
   public static void Register(HttpConfiguration config)
   {
       // Web API configuration and services
       // Configure Web API to use only bearer token authentication.
       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 }
       );
   }
}

即使我這樣做了:

   config.SuppressDefaultHostAuthentication();
   config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

Authorization: Bearer 2bTw5d8Vf4sKR9MNMqZsxIOPHp5qtXRTny5YEC_y7yWyrDLU0__q8U8Sbo7N7XBjPmxZXP18GRXjDVb3yQ9vpQnWXppRhVA8KDeGg2G5kITMxiOKvGMaKwyUGpORIeZ0UHyP9jA2fX9zPwzsCqHmq-LoGKls0MQNFjXgRGCCCvro5WPMAJcLs0kUoD_2W_TOTy9_T-koobw-DOivnazPo2Z-6kfXaIUuZ1YKdAbcSJKzpyPR_XrCt4Ma2fCf-LcpMPGo4gDFKfxWdId0XtfS9S-5cXmmOmGM4Y6MkAUK8O9sZlVrpmpvV0hjXF2QwfLtQViPyEctbTr1vPBNn014n60APwGSGnbUJBWMvJhqcjI5pWoubCmk7OHJrn052U_F3bDOi2ha1mVjvhVY1XMAuv2c3Pbyng2ZT_VuIQI7HjP4SLzV6JjRctfIPLEh67-DFp585sJkqgfSyM6h_vR2gPA5hDocaFs73Qa22QMaLRrHThU0HM8L3O8HgFl5oJtD
Referer: http://localhost:15379/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ro;q=0.6
Cookie: .AspNet.Cookies=E71BnnTMv8JJ4hS9K46Y2yIbGMQCTS4MVBWBXezUYCSGXPbUPNZh98Q0IElQ0zqGyhB7OpYfdh10Kcy2i5GrWGSiALPPtOZUmszfAYrLZwG2JYiU5MSW80OGZVMY3uG2U1aqvvKJpv7eJwJSOoS4meD_3Qy8SwRzTg8feZArAE-REEXSsbPfq4jQBUUbxfDAyuPVRsLNfkn4oIAwZTs85IulRZI5mLnLqOS7VLejMGIWhkuyOWvvISu1pjsP5FMDXNwDkjv2XCaOpRzZYUxBQJzkcdpDjwW_VO2l7HA263NaG_IBqYpLqG57Fi-Lpp1t5Deh2IRB0VuTqAgrkwxifoBDCCWuY9gNz-vNjsCk4kZc8QKxf7el1gu9l38Ouw6K1EZ9y2j6CGWmW1q-DobaK9JXOQEPm_LGyaGPM5to2vchTyjuieZvLBAjxhLKnXdy34Z7MZXLVIwmpSmyPvmbIuH9QzOvTWD-I1AQFJyCDw8

您是否看到SignalR使用令牌身份驗證更簡單的身份驗證方法?這種最終方法(如果我設法通過請求來抑制 cookie 的發送)在生產中是否可行?

在處理那個特定項目時,我最終只使用了 cookie 身份驗證和 CSRF,但我仍然對了解如何使用不記名令牌身份驗證對 WebApi 和 SignalR 進行身份驗證感興趣。

有關工作範例,請參閱此 GitHub 儲存庫。

我最終創建了一個OAuthBearerTokenAuthenticationProvider嘗試從 cookie 中檢索令牌的類。

public class OAuthBearerTokenAuthenticationProvider : OAuthBearerAuthenticationProvider
   {
       public override Task RequestToken(OAuthRequestTokenContext context)
       {
           var tokenCookie = context.OwinContext.Request.Cookies["BearerToken"];

           if (!String.IsNullOrEmpty(tokenCookie))
               context.Token = tokenCookie;

           return Task.FromResult<object>(null);
       }
   }

這是Startup處理身份驗證的類中的方法:

   public void ConfigureOAuth(IAppBuilder app)
   {
       OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
       {
           AllowInsecureHttp = true,
           TokenEndpointPath = new PathString("/token"),
           AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
           Provider = new AuthorizationServerProvider()
       };

       app.UseOAuthAuthorizationServer(OAuthServerOptions);
       app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
       {
           Provider = new OAuthBearerTokenAuthenticationProvider()
       });

   }

有關工作範例,請參閱此 GitHub 儲存庫。

希望這在某些時候對某人有所幫助。

引用自:https://stackoverflow.com/questions/32396586