繁体   English   中英

SignalR JWT声称IUserIdProvider中缺少。 JWT承载OnMessageReceived无法触发

[英]SignalR JWT claims missing in IUserIdProvider. JWT bearer OnMessageReceived not firing

我正在尝试使用.NET客户端和服务器设置SignalR。

我只需要一种自定义方法来提供已连接客户端的ID,并且看来唯一的方法是在实现IUserIdProvider接口时填充属于HubConnectionContext参数的声明。

在我的客户上,我正在构建一个按预期工作的JWT(验证它是否正确构建)。

在我的服务器上,我已按照此处提供的确切说明进行操作

但是,不会触发OnMessageReceived回调,因此令牌将被忽略,随后IUserIdProvider中的Claims数组为空。

值得注意的是,客户端连接时仍会调用IUserIdProvider。

这是我的客户端JWT生成代码:

        _hubConnection = new HubConnectionBuilder()
            .WithUrl($"{_hubUrl}", options => options.AccessTokenProvider = () =>
            {
                var jwtHandler = new JwtSecurityTokenHandler();
                var credentials = new SigningCredentials(_securityKey, SecurityAlgorithms.HmacSha256);
                var jwt = new JwtSecurityToken(claims: new[] { new Claim("Id", _id) }, signingCredentials: credentials);
                var tokenString = jwtHandler.WriteToken(jwt);
                return Task.FromResult(tokenString);
            })
            .Build();

这是我的启动ConfigureServices函数:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IUserIdProvider, MyIdProvider>();

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                LifetimeValidator = (before, expires, token, param) =>
                {
                    return true;
                },
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateActor = false,
                ValidateLifetime = true,
                IssuerSigningKey = SecurityKey
            };
            options.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    // breakpoints never hit...
                    var accessToken = context.Request.Query["access_token"];
                    var path = context.HttpContext.Request.Path;
                    if (!string.IsNullOrWhiteSpace(accessToken) &&
                        path.StartsWithSegments("myHub"))
                    {
                        context.Token = accessToken;
                    }
                    return Task.CompletedTask;
                }
            };
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        services.AddSignalR();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc(Version, new OpenApiInfo
            {
                Version = Version,
                Title = Name
            });
        });            
    }

最后是我的IUserIdProvider实现:

    public class MyIdProvider : IUserIdProvider
{
    public string GetUserId(HubConnectionContext connection)
    {
        var id = connection.User.Claims.First(x => x.Type == "Id").Value;
        return id;
    }
}

提前致谢。

要使此工作正常进行,必须解决几个问题。

首先,集线器需要[Authorize]属性,否则将永远不会调用OnMessageReceived。

其次,我缺少app.UseAuthentication(),它也是管道正常运行所必需的。

做出这些更改后,我的主张得到了正确的解释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM