Die SignalR-Authentifizierung ist fehlgeschlagen, wenn "Bearer" durch die Abfragezeichenfolge geleitet wurde

Ich möchte die Authentifizierung in SignalR aktivieren, während der Server in ASP.NET WebAPI gehostet wurde, das die OAuth Bearer-Authentifizierung verwendet und der Client AngularJS ist.

Auf der Clientseite übergebe ich das Bearer-Token ursprünglich über den HTTP-Header und es funktioniert gut mit der WebAPI. Da SignalR JavsScript jedoch das Hinzufügen von HTTP-Headern in nicht unterstütztconnection (Das liegt daran, dass WebSocket die Angabe von HTTP-Headern nicht unterstützt.) Ich muss das Bearer-Token mithilfe des Codes wie folgt über die Abfragezeichenfolge übergebenself.connection.qs = { Bearer: 'xxxxxx' };

Das Problem ist, dass mein SignalR auf der WebAPI-Seite immer 401 Unauthorized zurückgegeben hat.

Unten ist aufgeführt, was ich auf der WebAPI-Seite getan habe.

1 habe ich angegebenOAuthBearerAuthenticationOptions.Provider zuQueryStringEnabledOAuthBearerAuthenticationProvider, das ist eine Klasse, die ich von geerbt erstellt habeOAuthBearerAuthenticationProvider das kann Bearer-Token aus Abfragezeichenfolge abrufen. Code wie folgt.

    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);
        }
    }

Und registriert es wie folgt, während WebAPI gestartet wurde.

            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, In SignalR Teil habe ich ein Berechtigungsattribut wie folgt erstellt. Es wurde nichts geändert, nur um einen Haltepunkt hinzuzufügen.

    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);
        }
    }

Und es wurde registriert, als auch WebAPI gestartet wurde.

            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);
                });

Ich fand, als SignalR meineQueryStringEnabledOAuthBearerAuthenticationProvider.RequestToken wurde aufgerufen und das Inhaber-Token erfolgreich abgerufen. Aber dann, wenn SignalRBearerAuthorizeAttribute.AuthorizeHubConnection wurde der Parameter aufgerufenrequest.User immer noch nicht authentifiziert. Also gab es 401 zurück.

Kann mir jemand ein paar Ideen geben, was ich falsch gemacht habe, danke.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage