ASP .NET Core、SignalR (WebSocket) 未与 AuthorizeAttribute 连接
ASP .NET Core, SignalR (WebSocket) not connect with AuthorizeAttribute
在我的示例项目中,我遇到了 SignalR 和 WebSocket 传输协议的问题。
当我尝试在 AuthorizeAttribute 下连接集线器时,响应是:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:44341/chat/negotiate text/plain;charset=UTF-8 0
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Successfully validated the token.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4131ms 200 application/json
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44341/chat?id=bSfQQIMQk3-AWf7jTVfwsw&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYW5kcmVhLnRvc2F0byIsImV4cCI6MTUzNDQ5OTI5NywiaXNzIjoiY2xvdWRnZW4uY29kZWdlbi5jb20iLCJhdWQiOiJjbG91ZGdlbi5jb2RlZ2VuLmNvbSJ9.47NxR5bGKWqPyPDi7Yz_PaYJTHKUJcJyRWfftxJRBq4
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
客户端在 WebSocket 之后因服务器发送的事件而失败。使用长轮询一切正常。
我的客户:
this.connection = new HubConnectionBuilder()
.withUrl(environment.baseHubs + '/chat', {
accessTokenFactory: () => token,
logger: LogLevel.Trace
})
// .withHubProtocol(new JsonHubProtocol())
.withHubProtocol(new MessagePackHubProtocol())
.build();
this.connection.start()
.catch(this.errorConnection.bind(this))
.then(x => {
this.connection.invoke('GetUserContext').then(this.getUserContext.bind(this));
});
我的服务器代码:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Authentication:Issuer"],
ValidAudience = Configuration["Authentication:Audiance"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]))
};
});
分辨率:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Authentication:Issuer"],
ValidAudience = Configuration["Authentication:Audiance"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
在我的示例项目中,我遇到了 SignalR 和 WebSocket 传输协议的问题。 当我尝试在 AuthorizeAttribute 下连接集线器时,响应是:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:44341/chat/negotiate text/plain;charset=UTF-8 0 Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful. Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Successfully validated the token. Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful. Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4131ms 200 application/json Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44341/chat?id=bSfQQIMQk3-AWf7jTVfwsw&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYW5kcmVhLnRvc2F0byIsImV4cCI6MTUzNDQ5OTI5NywiaXNzIjoiY2xvdWRnZW4uY29kZWdlbi5jb20iLCJhdWQiOiJjbG91ZGdlbi5jb2RlZ2VuLmNvbSJ9.47NxR5bGKWqPyPDi7Yz_PaYJTHKUJcJyRWfftxJRBq4
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful. Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed. Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
客户端在 WebSocket 之后因服务器发送的事件而失败。使用长轮询一切正常。
我的客户:
this.connection = new HubConnectionBuilder()
.withUrl(environment.baseHubs + '/chat', {
accessTokenFactory: () => token,
logger: LogLevel.Trace
})
// .withHubProtocol(new JsonHubProtocol())
.withHubProtocol(new MessagePackHubProtocol())
.build();
this.connection.start()
.catch(this.errorConnection.bind(this))
.then(x => {
this.connection.invoke('GetUserContext').then(this.getUserContext.bind(this));
});
我的服务器代码:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Authentication:Issuer"],
ValidAudience = Configuration["Authentication:Audiance"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]))
};
});
分辨率:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Authentication:Issuer"],
ValidAudience = Configuration["Authentication:Audiance"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});