我使用隐式授权流程,它工作得非常完美。NG应用程序重定向到IdentityServer的登录页面,在那里用户登录。然后浏览器将带有访问令牌的重定向返回到NG应用程序。然后使用该令牌调用API,并建立与SignalR的通信。我认为我已经阅读了所有可用的资料(见下面的来源)。
由于SignalR使用不支持标头的WebSockets,因此令牌应该在查询字符串中发送。然后在API侧,提取并设置请求的令牌,就像在标头中一样。然后验证令牌并授权用户。
API没有任何问题,用户被授权并且声明可以在API侧检索。所以既然SignalR不需要任何特殊配置,那么IdentityServer也应该没有问题。我是对的吗?
当我不在SignalR hub上使用[Authorized]属性时,握手成功。这就是为什么我认为我使用的docker基础设施和反向代理没有问题(代理被设置为启用WebSockets)。
因此,在未授权的情况下,SignalR可以工作。有授权时,NG客户端在握手期间会收到以下响应:
Failed to load resource: the server responded with a status of 401
Error: Failed to complete negotiation with the server: Error
Error: Failed to start the connection: Error
请求为:
Request URL: https://publicapi.localhost/context/negotiate?signalr_token=eyJhbGciOiJSUz... (token is truncated for simplicity)
Request Method: POST
Status Code: 401
Remote Address: 127.0.0.1:443
Referrer Policy: no-referrer-when-downgrade
我得到的回复:
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:4200
content-length: 0
date: Fri, 01 Jun 2018 09:00:41 GMT
server: nginx/1.13.10
status: 401
vary: Origin
www-authenticate: Bearer
根据日志,令牌已经成功验证。我可以包含完整的日志,但是我怀疑问题出在哪里。因此,我将在这里包含那部分内容:
根据日志,令牌已成功验证。我可以包含完整日志,但我怀疑问题所在。因此,在此处包含该部分:[09:00:41:0561 Debug] Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler AuthenticationScheme: Identity.Application was not authenticated.
[09:00:41:0564 Debug] Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler AuthenticationScheme: Identity.Application was not authenticated.
我在日志文件中看到了这些信息,但不确定它们的含义。我包含了获取和提取令牌以及身份验证配置的API代码部分。
我收到的日志信息和API代码中获取和提取令牌以及身份验证配置的部分让我感到困惑。
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddIdentityServerAuthentication(options =>
{
options.Authority = "http://identitysrv";
options.RequireHttpsMetadata = false;
options.ApiName = "publicAPI";
options.JwtBearerEvents.OnMessageReceived = context =>
{
if (context.Request.Query.TryGetValue("signalr_token", out StringValues token))
{
context.Options.Authority = "http://identitysrv";
context.Options.Audience = "publicAPI";
context.Token = token;
context.Options.Validate();
}
return Task.CompletedTask;
};
});
系统中没有其他错误或异常。我可以对应用程序进行调试,一切似乎都很好。
这些日志行的含义是什么? 如何在授权期间调试正在发生的事情?
编辑:我差点忘了提到,我认为问题出在身份验证方案上,所以我将每个方案都设置为我认为需要的方案。然而,可悲的是它没有起到帮助作用。
我有点无头绪,所以我感谢任何建议。谢谢。
信息来源: