路过的香蕉 · obj, end = ...· 2 月前 · |
纯真的沙滩裤 · Pyqt 滚动条的小demo_pyqt ...· 6 月前 · |
聪明的啤酒 · spark - tasks is ...· 1 年前 · |
我在.NET 5上使用ASPNet核心SignalR。只要我在集线器本身上有Authorize属性,授权就可以在.NET和Angular中工作。对于WPF客户端,它成功了。
服务器集线器是一个非常标准的Microsoft.AspNetCore.SignalR.Hub。
// [Authorize] This works for both WPF and Angular
public class MyHub: Hub
[Authorize] // This only works for WPF. For Angular it fails
async Task<string> SubscribeAuthorize()
... stuff
async Task<string> SubscribeUnauthorized()
... stuff
}
当我查看Angular故障期间的服务器日志时,我看到:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Successfully validated the token.
不久之后就是...
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
// WPF成功
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 POST https://localhost:44307/WorkspaceEditHub/negotiate?negotiateVersion=1 - 0
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Successfully validated the token.
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint '/WorkspaceEditHub/negotiate'
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint '/WorkspaceEditHub/negotiate'
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/1.1 POST https://localhost:44307/WorkspaceEditHub/negotiate?negotiateVersion=1 - 0 - 200 316 application/json 7.7400ms
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 GET https://localhost:44307/WorkspaceEditHub?id=x4aYtUdkDXIHTcwXLuictw - -
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Successfully validated the token.
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint '/WorkspaceEditHub'
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful.
//角度故障
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2 OPTIONS https://localhost:44307/WorkspaceEditHub/negotiate - -
Microsoft.AspNetCore.Cors.Infrastructure.CorsService: Information: CORS policy execution successful.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/2 OPTIONS https://localhost:44307/WorkspaceEditHub/negotiate - - - 204 - - 6.7752ms
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2 POST https://localhost:44307/WorkspaceEditHub/negotiate text/plain;charset=UTF-8 0
Microsoft.AspNetCore.Cors.Infrastructure.CorsService: Information: CORS policy execution successful.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Successfully validated the token.
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint '/WorkspaceEditHub/negotiate'
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint '/WorkspaceEditHub/negotiate'
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/2 POST https://localhost:44307/WorkspaceEditHub/negotiate text/plain;charset=UTF-8 0 - 200 273 application/json 38.9649ms
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 GET https://localhost:44307/WorkspaceEditHub?id=
<long bunch of stuff that isn't in the WPF log> - -
Microsoft.AspNetCore.Cors.Infrastructure.CorsService: Information: CORS policy execution successful.
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint '/WorkspaceEditHub'
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint '/WorkspaceEditHub'
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/1.1 GET https://localhost:44307/WorkspaceEditHub?id=<long bunch of stuff that isn't in the WPF log> - - - 101 - - 99.6336ms
最后,下面是我如何在WPF中设置集线器(这是可行的)
var proxy = WebRequest.DefaultWebProxy;
proxy = WebRequest.DefaultWebProxy;
proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
SignalRHub = new HubConnectionBuilder().WithUrl(url, options =>
options.AccessTokenProvider = () => Task.FromResult(_credentials.Token);
options.Proxy=proxy;
}).Build();
await SignalRHub.StartAsync();
string jsonResult=await SignalRHub.InvokeAsync<string>("SubscribeAuthorize");
下面是我如何在Angular中设置它(失败了)。
const options: IHttpConnectionOptions = {
accessTokenFactory: () => {
return this.oidcSecurityService.getToken();
this.hubConnection = new HubConnectionBuilder().withUrl(url, options).build();
await this.hubConnection.start();
let result = await this.hubConnection.invoke("SubscribeAuthorize");
我感觉我真的很接近,因为正如前面提到的,如果Authorize是在Hub级别而不是方法级别工作,那么它使用的是完全相同的客户端代码。
发布于 2021-07-08 12:39:37
想出了一个解决方案。像许多服务器的东西一样,这个解决方案看起来更像是拼写成分,而不是实际的代码。
我不确定为什么Authorize在中心级别时能够找到令牌,而在方法级别上找不到它,或者为什么WPF工作,但显然Angular客户端设置请求的方式略有不同。
在ConfigureServices下的Startup.cs中
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
// other options...
options.Events = new JwtBearerEvents
OnMessageReceived = context =>
var accessToken = context.Request.Query["access_token"];
// If the request is for our hub...
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/hub"))) // Your hub path here