WebSockets 和身份验证与身份服务器4.



我正在使用.net core 1.1和identityserver 4来获取令牌并验证用户。Web API 可以正常工作,从标头读取持有者令牌并获取用户主体声明。

现在我想使用 websocket(不是 SignalR)来发送通知。我可以打开一个 ws://通道(或 wss),但令牌不与标头一起发送,因此在 .net 核心应用程序中我没有用户的信息(用户声明和标识)。

如何通过 websocket 对用户进行身份验证?我进行了搜索,但找不到任何有用的信息。

谢谢

WebSocket 中间件中的身份验证有两个主要问题:

应手动调用授权

首先,授权不适用于 Web 套接字请求(因为它不是可以用授权属性标记的控制器)。 这就是为什么在 WebSocket 中间件中,您需要自己调用授权。这很容易通过调用HttpContext对象的扩展方法来实现AuthenticateAsync

因此,您的中间件将如下所示:

public class WebSocketMiddleware
{
private readonly RequestDelegate next;
public WebSocketMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await this.next.Invoke(context);
return;
}
AuthenticateResult authenticateResult = 
await context.AuthenticateAsync(OAuthValidationDefaults.AuthenticationScheme);
....
});
}

因此,使用身份验证结果,您可以检查用户是否已通过身份验证,然后访问经过身份验证的用户信息。

将持有者令牌传递给 Web 套接字请求

对于 Web 套接字连接,默认的授权标头不起作用,因为 WebSockets JS API 不允许设置自定义参数。为了解决此限制,访问令牌经常在查询字符串中传递。

要使身份验证中间件使用它,您需要更新身份验证验证选项。这基本上可以在启动脚本中完成,如下所示:

services
.AddAuthentication()
.AddOAuthValidation(options =>
{
options.Events = new OAuthValidationEvents
{
// Note: for Web Socket connections, the default Authorization header does not work,
// because the WebSockets JS API doesn't allow setting custom parameters.
// To work around this limitation, the access token is retrieved from the query string.
OnRetrieveToken = context =>
{
context.Token = context.Request.Query["access_token"];
return Task.FromResult(0);
}
};
});

以下代码可用作在连接初始化期间将访问令牌添加到 Web 套接字 URL 的示例:

const protocol = location.protocol === "https:" ? "wss:" : "ws:";
const wsUri = protocol + "//" + window.location.host + "/ws" + "?access_token=" + token;
this.socket = new WebSocket(wsUri);

相关内容

  • 没有找到相关文章

最新更新