簡體   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