3
votes

We have an api (.net core 2.2) which use IdentityServerAuthenticationDefaults.AuthenticationScheme for all the controllers which works fine.

We now decide to add SignalR Hub for a conference service. The hub is working fine only if we remove the authorize attribute [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]

We did try to handle the token in the query using the following both methods (TokenRetriever or JwrBearerEvents) :

services.AddAuthentication()
        .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
        {
            options.Authority = AuthURL;
            options.SupportedTokens = SupportedTokens.Jwt;
            options.RequireHttpsMetadata = HttpsSetting;
            options.ApiName = APIs.API_Commerce;
            options.TokenRetriever = new Func<HttpRequest, string>(req =>
            {
                var fromHeader = TokenRetrieval.FromAuthorizationHeader();
                var fromQuery = TokenRetrieval.FromQueryString();
                return fromHeader(req) ?? fromQuery(req);
            });
            options.JwtBearerEvents.OnMessageReceived = context =>
                {
                    var accessToken = context.Request.Query["access_token"];

                    // If the request is for our hub...
                    var path = context.HttpContext.Request.Path;
                    if (!string.IsNullOrEmpty(accessToken) &&
                        (path.StartsWithSegments("/hubs/")))
                    {
                        // Read the token out of the query string
                        context.Token = accessToken;
                    }
                    return Task.CompletedTask;
                };
        });

For some reason theses only fire when we call controllers but ignore all invoked methods from the client.

Note that we have an AuthServer which provide the tokens and an API. We are using angular 7 with aspnet/signalr module for the client side.

1

1 Answers

3
votes

I found the problem...

  1. app.UseAuthentication() was added in Configure
  2. Add default scheme to authentication and remove onmessagereceive ->

            services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
        })
        .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
        {
            options.Authority = AuthURL;
            options.SupportedTokens = SupportedTokens.Jwt;
            options.RequireHttpsMetadata = HttpsSetting;
            options.ApiName = APIs.API_Commerce;
            options.TokenRetriever = new Func<HttpRequest, string>(req =>
            {
                var fromHeader = TokenRetrieval.FromAuthorizationHeader();
                var fromQuery = TokenRetrieval.FromQueryString();
                return fromHeader(req) ?? fromQuery(req);
            });
        });
    

Just to mention with .net core 2.2 u must specified an origin (withOrigins) and cannot use Any..