【发布时间】:2019-04-30 10:11:10
【问题描述】:
我正在尝试使用 .NET 客户端和服务器设置 SignalR。
我只需要一种自定义方法来提供已连接客户端的 ID,而且似乎唯一的方法是在实现 IUserIdProvider 接口时填充作为 HubConnectionContext 参数一部分的声明。
在我的客户端上,我正在构建一个按预期工作的 JWT(验证它的构建是否正确)。
在我的服务器上,我已按照here提供的确切说明进行操作
但是,OnMessageReceived 回调不会触发,因此令牌被忽略,随后 IUserIdProvider 中的声明数组为空。
值得注意的是,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();
这是我的启动配置服务功能:
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;
}
}
提前致谢。
【问题讨论】:
-
你检查过是不是CORS问题吗?
-
试过让一切都无济于事。
标签: c# asp.net-core jwt signalr