承载"通过&QUOT时SignalR认证失败;通过查询字符串 [英] SignalR authentication failed when passing "Bearer" through query string
问题描述
我想启用身份验证SignalR当服务器在ASP.NET的WebAPI举办这我使用OAuth承载authrntication和客户端是AngularJS。
I'd like to enable authentication in SignalR while the server was hosted in ASP.NET WebAPI which I'm using OAuth Bearer authrntication and the client is AngularJS.
在客户端我本来通过HTTP头承载令牌,并将其与的WebAPI效果很好。但由于SignalR JavsScript不支持连接时添加的HTTP标头
(这是因为WebSocket的不支持指定的HTTP头),我需要通过传递承载令牌通过查询字符串在code像 self.connection.qs = {承载:'XXXXXX'};
On client side I originally pass the Bearer token through HTTP header and it works well with the WebAPI. But since SignalR JavsScript doesn't support adding HTTP headers in connection
(it's because WebSocket doesn't support specifying HTTP headers) I need to pass the Bearer token through query string by using the code like self.connection.qs = { Bearer: 'xxxxxx' };
问题是对的WebAPI一边我SignalR总是返回401未授权。
The problem is on the WebAPI side my SignalR always returned 401 Unauthorized.
下面是我所做的侧面的WebAPI
Below is what I did on the WebAPI side.
1,我指定的 OAuthBearerAuthenticationOptions.Provider
到 QueryStringEnabledOAuthBearerAuthenticationProvider
,这是我从创建<$ C继承的类$ C> OAuthBearerAuthenticationProvider ,可以从查询字符串检索承载令牌。 code如下。
1, I specified OAuthBearerAuthenticationOptions.Provider
to QueryStringEnabledOAuthBearerAuthenticationProvider
, which is a class I created inherited from OAuthBearerAuthenticationProvider
that can retrieve Bearer token from query string. Code as below.
public class QueryStringEnabledOAuthBearerAuthenticationProvider : OAuthBearerAuthenticationProvider
{
private readonly string _name;
public QueryStringEnabledOAuthBearerAuthenticationProvider()
: this(OAuthDefaults.AuthenticationType)
{
}
public QueryStringEnabledOAuthBearerAuthenticationProvider(string name)
{
_name = name;
}
public override Task RequestToken(OAuthRequestTokenContext context)
{
// try to read token from base class (header) if possible
base.RequestToken(context).Wait();
if (string.IsNullOrWhiteSpace(context.Token))
{
// try to read token from query string
var token = context.Request.Query.Get(_name);
if (!string.IsNullOrWhiteSpace(token))
{
context.Token = token;
}
}
return Task.FromResult(null);
}
}
和它注册为更低的WebAPI就开始了。
And registered it as below while WebAPI was started.
var options = new OAuthBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = AuthenticationType,
Provider = new QueryStringEnabledOAuthBearerAuthenticationProvider(),
AccessTokenFormat = _accessTokenFormat,
};
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
app.UseOAuthBearerAuthentication(options);
2,在SignalR部分我创建了一个授权如下属性。什么都没有改变只是用来添加断点。
2, In SignalR part I created an authorize attribute as below. Nothing changed just to be used to add break point.
public class BearerAuthorizeAttribute : AuthorizeAttribute
{
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
return base.AuthorizeHubConnection(hubDescriptor, request);
}
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
return base.AuthorizeHubMethodInvocation(hubIncomingInvokerContext, appliesToMethod);
}
}
和它注册时的WebAPI开始为好。
And registered it when WebAPI started as well.
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
EnableJavaScriptProxies = false
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
// Require authentication for all hubs
var authorizer = new BearerAuthorizeAttribute();
var module = new AuthorizeModule(authorizer, authorizer);
GlobalHost.HubPipeline.AddModule(module);
});
我发现,当SignalR连接我的 QueryStringEnabledOAuthBearerAuthenticationProvider.RequestToken
被调用,它承载获取成功的象征。但是当SignalR BearerAuthorizeAttribute.AuthorizeHubConnection
被调用参数 request.User
仍然未通过身份验证。因此,它返回401。
I found, when SignalR connected my QueryStringEnabledOAuthBearerAuthenticationProvider.RequestToken
was invoked and it retrieved Bearer token successfully. But then when SignalR BearerAuthorizeAttribute.AuthorizeHubConnection
was invoked the parameter request.User
still not authenticated. So it returned 401.
谁能给我一些想法,什么是错的我做了,谢谢。
Can anyone give me some ideas on what's wrong I did, thanks.
推荐答案
我用头,这是我如何解决它。
I'm using headers, this is how I solved it
var authData = localStorageService.get('authorizationData');
var token = authData.token;
$.signalR.ajaxDefaults.headers = { Authorization: "Bearer " + token };
希望它能帮助
这篇关于承载&QUOT;通过&QUOT时SignalR认证失败;通过查询字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!