[英]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.