如何使用JWT授权SignalR Core Hub方法

Mak*_*kla 3 authentication signalr openiddict asp.net-core-signalr

我在OpenIddict的ASP.NET Core 2.0应用程序中使用JWT身份验证.

我在SignalR握手后跟踪这个线程和调用AuthorizeWithJWT方法的想法.但是现在,我不知道我应该在AuthorizeWithJWT方法中设置什么,所以我可以使用它[Authorize(Roles="Admin")].

我试着设置上下文用户,但它只是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
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用authorize属性:

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

Kév*_*let 6

我强烈建议您继续在握手级别进行身份验证,而不是使用您在SignalR级别实现的自定义和非标准解决方案.

假设您正在使用验证处理程序,您可以强制它从查询字符串中检索访问令牌:

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

                return Task.CompletedTask;
            };
        });
}
Run Code Online (Sandbox Code Playgroud)

或者OnMessageReceived如果你想使用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;
            },
        };
    });
Run Code Online (Sandbox Code Playgroud)

不需要进行任何其他更改.