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.