3

I am using JWT authentication in my ASP.NET Core 2.0 application with OpenIddict.

I am following idea in this thread and calling AuthorizeWithJWT method after SignalR handshake. But now, I do not know what should I set in AuthorizeWithJWT method so I can use [Authorize(Roles="Admin")] for example.

I tried with setting context user, but it is readonly:

public class BaseHub : Hub
{    
    public async Task AuthorizeWithJWT(string AccessToken)
    {
        //get user claims from AccesToken
        this.Context.User = user;  //error User is read only
    }
}

And using authorize attribute:

public class VarDesignImportHub : BaseHub
{
    [Authorize(Roles = "Admin")]
    public async Task Import(string ConnectionString)
    {
    }
}

1 Answer 1

7

I strongly encourage you to continue doing authentication at the handshake level instead of going with a custom and non-standard solution you'd implement at the SignalR level.

Assuming you're using the validation handler, you can force it to retrieve the access token from the query string:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication()
        .AddOAuthValidation(options =>
        {
            options.Events.OnRetrieveToken = context =>
            {
                context.Token = context.Request.Query["access_token"];

                return Task.CompletedTask;
            };
        });
}

Or OnMessageReceived if you want to use JWTBearer:

services.AddAuthentication()
    .AddJwtBearer(o =>
    {
        o.Events = new JwtBearerEvents()
        {
            OnMessageReceived = context =>
            {
                if (context.Request.Path.ToString().StartsWith("/HUB/"))
                    context.Token = context.Request.Query["access_token"];
                return Task.CompletedTask;
            },
        };
    });

No other change should be required.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes this would be a valid case, but as explain in github thread (link1, link2) there are some security risks with this approach. Because access_token in query is public (you can log it...). Will do that, if no other approach is possible.
But one time access token could do it? @Pinpoint What do you think?
The only "risk" is that the access token will be included in the logs (which is clearly explained in the OAuth2 bearer specification). To avoid that, you could disable the logging traces including the query string using the filtering API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.