【发布时间】:2014-07-15 01:56:12
【问题描述】:
我想在 SignalR 中启用身份验证,而服务器托管在 ASP.NET WebAPI 中,我使用 OAuth Bearer 身份验证并且客户端是 AngularJS。
在客户端,我最初通过 HTTP 标头传递 Bearer 令牌,它与 WebAPI 配合得很好。但由于 SignalR JavsScript 不支持在 connection 中添加 HTTP 标头(这是因为 WebSocket 不支持指定 HTTP 标头),我需要使用 self.connection.qs = { Bearer: 'xxxxxx' }; 之类的代码通过查询字符串传递 Bearer 令牌
问题出在 WebAPI 端,我的 SignalR 总是返回 401 Unauthorized。
以下是我在 WebAPI 方面所做的。
1,我将OAuthBearerAuthenticationOptions.Provider指定为QueryStringEnabledOAuthBearerAuthenticationProvider,这是我创建的继承自OAuthBearerAuthenticationProvider的类,可以从查询字符串中检索承载令牌。代码如下。
并在 WebAPI 启动时将其注册如下。
var options = new OAuthBearerAuthenticationOptions { AuthenticationMode = AuthenticationMode.Active, 身份验证类型 = 身份验证类型, 提供者 = 新的 QueryStringEnabledOAuthBearerAuthenticationProvider(), AccessTokenFormat = _accessTokenFormat, }; config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); app.UseOAuthBearerAuthentication(选项);2,在 SignalR 部分中,我创建了一个授权属性,如下所示。只是为了添加断点而没有改变。
公共类 BearerAuthorizeAttribute : AuthorizeAttribute { public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) { 返回 base.AuthorizeHubConnection(hubDescriptor, request); } 公共覆盖 bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool applyToMethod) { 返回 base.AuthorizeHubMethodInvocation(hubIncomingInvokerContext, applyToMethod); } }并在 WebAPI 启动时注册它。
app.Map("/signalr", 地图 => { // 设置 CORS 中间件在 SignalR 之前运行。 // 默认情况下,这将允许所有来源。你可以 // 通过以下方式配置源集和/或 http 动词集 // 提供具有不同策略的 cors 选项。 map.UseCors(CorsOptions.AllowAll); var hubConfiguration = 新的 HubConfiguration { // 您可以通过取消注释下面的行来启用 JSONP。 // JSONP 请求是不安全的,但一些较旧的浏览器(和一些 // IE 版本)需要 JSONP 才能跨域工作 // EnableJSONP = true EnableJavaScriptProxies = false }; // 运行 SignalR 管道。我们没有使用 MapSignalR // 因为这个分支已经在“/signalr”下运行 // 小路。 map.RunSignalR(hubConfiguration); // 要求对所有集线器进行身份验证 var authorizer = new BearerAuthorizeAttribute(); var module = new AuthorizeModule(授权人,授权人); GlobalHost.HubPipeline.AddModule(module); });我发现,当 SignalR 连接时,我的 QueryStringEnabledOAuthBearerAuthenticationProvider.RequestToken 被调用并成功检索了 Bearer 令牌。但是当 SignalR BearerAuthorizeAttribute.AuthorizeHubConnection 被调用时,参数 request.User 仍然没有经过身份验证。所以它返回了 401。
谁能给我一些关于我做错了什么的想法,谢谢。
【问题讨论】:
-
您不必为了指定自定义 RequestToken 行为而从 OAuthBearerAuthenticationProvider 继承。您可以设置 OAuthBearerAuthenticationProvider 实例的 OnRequestToken 委托。
-
我已经在这里回答了这个问题stackoverflow.com/questions/26657296/…
标签: angularjs asp.net-web-api signalr signalr.client bearer-token