我使用.net core 1.1和identityserver 4来获取令牌并验证用户。 web api可以很好地从标题中读取持有者令牌并获得用户主要声明。
现在我想使用websocket(而不是SignalR)来发送通知。我可以打开一个ws:// channel(或wss),但令牌不随头文件一起发送,所以在.net核心应用程序中我没有用户信息(用户声明和身份)。
如何通过websocket验证用户身份?我进行了搜索但找不到任何有用的信息。
由于
答案 0 :(得分:9)
WebSocket中间件中的身份验证有两个主要问题:
应手动调用授权
首先,授权不适用于Web套接字请求(因为它不是可以用Authorize属性标记的控制器)。
这就是为什么在WebSocket中间件中你需要自己调用授权。通过调用.player {
top: 200px; /* whatever value you want the bottom of element to be from top */
margin-top: -100%; /* bring the element back up so the bottom is where the top value set above is */
}
对象的AuthenticateAsync
扩展方法,可以轻松实现此目的。
因此,您的中间件看起来像这样:
HttpContext
因此,使用身份验证结果,您可以检查用户是否经过身份验证,然后访问经过身份验证的用户信息。
将持有人令牌传递给网络套接字请求
对于Web Socket连接,默认的Authorization标头不起作用,因为WebSockets JS API不允许设置自定义参数。要解决此限制,访问令牌会在查询字符串中经常传递。
要使身份验证中间件能够使用它,您需要更新身份验证验证选项。这基本上可以在您的启动脚本中完成,如下所示:
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套接字URL添加访问令牌的示例:
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);
}
};
});