在MMS文档中提到您可以使用访问令牌授权您的Signalr:
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub", {
accessTokenFactory: () => {
// Get and return the access token.
// This function can return a JavaScript Promise if asynchronous
// logic is required to retrieve the access token.
}
})
.build();
您可以在后端代码(带有iuseridProvider)中使用this
public class EmailBasedUserIdProvider : IUserIdProvider
{
public virtual string GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(ClaimTypes.Email)?.Value!;
}
}
我没有适当的令牌可以传递到AccessTokenFactory,但是我的客户端上有UserId,我想使用getUserId方法使用此用户,因此我可以区分聊天属于用户的聊天,而不是整个令牌。是否可以将另一个价值(或仅是一个主张)传递给HubConnectionBuilder?例如:
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub", {
accessTokenFactory: () => {
// Pass your value or just a custom claim so it could be retrive on server side
}
})
.build();
回答为时已晚?
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub", {
accessTokenFactory: () => {
return "this:is:my:token";
}
})
.build();
然后在您的服务器上您可以拥有
public class CustomTokenSchemeHandler : AuthenticationHandler<CustomTokenSchemeOptions>
{
...
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);
var token = Context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
if (token is null)
{
return AuthenticateResult.NoResult();
}
string[] userInfoArray = token.Split(":");
var claims = new[]
{
new Claim(ClaimTypes.Name, userInfoArray[1]),
new Claim(ClaimTypes.Sid, userInfoArray[0])
// add whatever else you want here
};
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, Scheme.Name));
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);
}
...
}
在您的服务配置中:
builder.Services.AddAuthentication("CustomToken")
.AddScheme<CustomTokenSchemeOptions, CustomTokenSchemeHandler>("CustomToken");
更多或更少。一些连接元素/样板代码可能缺少,但这应该为您提供一般的想法。