Сбой аутентификации SignalR при передаче «Bearer» через строку запроса

Я хотел бы включить аутентификацию в SignalR, когда сервер был размещен в ASP.NET WebAPI, где я использую аутентификацию OAuth Bearer, а клиент - AngularJS.

На стороне клиента я изначально передаю токен Bearer через HTTP-заголовок, и он хорошо работает с WebAPI. Но поскольку SignalR JavsScript не поддерживает добавление заголовков HTTP вconnection (это потому, что WebSocket не поддерживает указание заголовков HTTP) Мне нужно передать токен Bearer через строку запроса, используя такой код, какself.connection.qs = { Bearer: 'xxxxxx' };

Проблема на стороне WebAPI, мой SignalR всегда возвращал 401 Несанкционированный.

Ниже то, что я сделал на стороне 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 я создал атрибут авторизации, как показано ниже. Ничего не изменилось, только чтобы добавить точку останова.

    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 был вызван, и он успешно получил токен на предъявителя. Но тогда, когда SignalRBearerAuthorizeAttribute.AuthorizeHubConnection был вызван параметрrequest.User до сих пор не заверены. Так вернулось 401.

Может кто-нибудь дать мне несколько идей о том, что я не так сделал, спасибо.

Ответы на вопрос(2)

Ваш ответ на вопрос