Asp.net
WebAPI 和 SignalR Web 應用程序 - 身份驗證和授權
我有一個
WebAPI解決方案並且我使用token authentication,所以流程如下:
- 使用者嘗試使用
usernameand登錄password- 如果憑據正確,他將獲得一個令牌,以便在以下請求中使用(放置在
AJAX請求的標頭中)。現在
SignalR開始發揮作用。由於它使用WebSockets,因此您無法傳遞標頭。在尋找解決方案時,我遇到了以下問題:
- 實際上將標頭傳遞給
SignalR- 而不是選項,因為它強制SignalR使用longPolling.
$.signalR.ajaxDefaults.headers = { Authorization: "Bearer " + token };
token將用於驗證WebAPI呼叫的相同傳遞為query string/ 或將其儲存在 cookie 中SignalR,然後創建一個提供程序,以某種方式將令牌解包並擴展為身份。我關注了這篇博文,但我似乎遺漏了一些東西。- 再次將令牌作為/ 或 cookie傳遞
query string,但這次創建一個自定義集線器或方法。 又是一篇關於此的博文。此解決方案的問題在於令牌的方法。Authorize Attribute``AuthorizeSignalR``Unprotect- 最後也是最簡單的解決方案是也啟用
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 進行身份驗證感興趣。
我最終創建了一個
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() }); }希望這在某些時候對某人有所幫助。