加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – 通过查询字符串传递“Bearer”时SignalR身份验证失

发布时间:2020-12-17 10:26:46 所属栏目:安全 来源:网络整理
导读:我想在SignalR中启用身份验证,而服务器托管在ASP.NET WebAPI中,我正在使用OAuth Bearer autrntication,客户端是AngularJS. 在客户端,我最初通过HTTP标头传递Bearer令牌,它适用于WebAPI.但由于SignalR JavsScript不支持在连接中添加HTTP头(因为WebSocket不支
我想在SignalR中启用身份验证,而服务器托管在ASP.NET WebAPI中,我正在使用OAuth Bearer autrntication,客户端是AngularJS.

在客户端,我最初通过HTTP标头传递Bearer令牌,它适用于WebAPI.但由于SignalR JavsScript不支持在连接中添加HTTP头(因为WebSocket不支持指定HTTP头),我需要使用self.connection.qs = {Bearer:’等代码通过查询字符串传递Bearer令牌. xxxxxx’};

问题出在WebAPI方面,我的SignalR总是返回401 Unauthorized.

以下是我在WebAPI方面所做的.

1,我将OAuthBearerAuthenticationOptions.Provider指定给QueryStringEnabledOAuthBearerAuthenticationProvider,这是我创建的一个继承自OAuthBearerAuthenticationProvider的类,可以从查询字符串中检索Bearer令牌.代码如下.

    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启动时将其注册如下.

            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部分,我创建了一个authorize属性,如下所示.没有任何改变只是用于添加断点.

    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启动时注册它.

            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并成功检索了Bearer令牌.但是当调用SignalR BearerAuthorizeAttribute.AuthorizeHubConnection时,参数request.User仍未经过身份验证.所以它返回401.

谁能给我一些关于我做错了什么的想法,谢谢.

我正在使用标题,这就是我解决它的方式
var authData = localStorageService.get('authorizationData');
var token = authData.token;
$.signalR.ajaxDefaults.headers = { Authorization: "Bearer " + token };

希望能帮助到你

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读