【发布时间】:2016-11-11 22:56:11
【问题描述】:
我有一个WebAPI 解决方案,我使用token authentication,所以流程如下:
- 用户尝试使用
username和password登录 - 如果凭据正确,他将获得一个令牌,以便在以下请求中使用(放置在
AJAX请求的标头中)。
现在SignalR 开始发挥作用了。由于它使用WebSockets,因此您无法传递标头。
在寻找解决方案时,我遇到了以下问题:
- 实际上将标头传递给
SignalR- 这不是一个选项,因为它强制SignalR使用longPolling。
$.signalR.ajaxDefaults.headers = { Authorization: "Bearer " + token };
将用于验证
WebAPI调用的token传递为query string/或将其存储在SignalR的cookie 中,然后创建一个提供程序,以某种方式将令牌解包并扩展为身份。 I followed this blog post 但我似乎遗漏了什么。再次将令牌作为
query string/或 cookie 传递,但这次创建自定义Authorize Attribute到AuthorizeSignalR集线器或方法。 Again a blog post about this. 这个解决方案的问题在于令牌上的Unprotect方法。最后也是最简单的解决方案是同时启用
cookie authentication,继续使用bearer token authentication进行WebAPI呼叫,并让OWIN Middleware授权集线器上的呼叫。 (这个解决方案确实有效)。
现在,问题是使用WebAPI 应用程序的默认模板和Individual User Accounts(因此使用令牌身份验证),每当我向API 发送AJAX 请求时,它也会发送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 的发送)在生产中可行吗?
【问题讨论】:
-
我还没有尝试过,但是,如果您还没有阅读,这里有两个链接可以参考:asp.net/signalr/overview/security/introduction-to-security 和 asp.net/signalr/overview/security/hub-authorization
标签: asp.net authentication cookies asp.net-web-api signalr