承载"通过&QUOT时SignalR认证失败;通过查询字符串 [英] SignalR authentication failed when passing "Bearer" through query string

查看:446
本文介绍了承载"通过&QUOT时SignalR认证失败;通过查询字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想启用身份验证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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆