在授权 Web 套接字之前追加授权 Header
Append Authorization Header Before Authorizing Web Sockets
我正在重构我的 API 以使用内置的 .Net 身份验证而不是 IdentityServer4
在我的旧代码中,我会将身份验证令牌附加到 websocket 地址并使用中间件
注入 header
public class SignalRQueryStringAuthMiddleware
{
private readonly RequestDelegate _next;
public SignalRQueryStringAuthMiddleware(RequestDelegate next)
{
_next = next;
}
// Convert incomming qs auth token to a Authorization header so the rest of the chain
// can authorize the request correctly
public async Task Invoke(HttpContext context)
{
if (context.Request.Query.TryGetValue("A5S0kT0k", out var token))
{
context.Request.Headers.Add("Authorization", "Bearer " + token.First());
}
await _next.Invoke(context);
}
}
我可以看到我的中间件正在按预期执行并附加了正确的授权 Header。
然而,在我的启动过程中,我的授权似乎从未被调用,它直接移动到连接到 websocket'
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(cfg => {
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.Events = new JwtBearerEvents
{
OnMessageReceived = async (ctx) =>
{
Console.WriteLine(ctx.Token);
},
OnTokenValidated = async (ctx) =>
{
Console.WriteLine("BreakPoint");
},
OnAuthenticationFailed = async (ctx) =>
{
Console.WriteLine("Breakpoint");
}
};
cfg.TokenValidationParameters = tokenValidationParameters;
});
这是我的管道在配置中的执行顺序
app.UseSignalRQueryStringAuth();
app.UseAuthentication();
app.UseSignalR(routes =>
{
routes.MapHub<DefaultServiceHubBase<MessageDTO>>("/messages");
routes.MapHub<DefaultServiceHubBase<ConversationDTO>>("/conversations");
routes.MapHub<InMemoryHub<UserLocationDTO>>("/user-locations");
});
我配置我的管道,以便首先命中中间件,但我永远无法命中 JWTBearer 部分中的任何断点的身份验证,但是,如果我制作标准的 HttpRequest,一切正常吗?
我的 OnMessageReceived
被忽略了,它直接转到我中心的 onconnect 函数 为什么会这样?
不知道为什么,但事实证明我还需要添加一个默认的挑战模式
services.AddAuthentication(options =>
{
// Identity made Cookie authentication the default.
// However, we want JWT Bearer Auth to be the default.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
中找到了这个
我正在重构我的 API 以使用内置的 .Net 身份验证而不是 IdentityServer4
在我的旧代码中,我会将身份验证令牌附加到 websocket 地址并使用中间件
注入 headerpublic class SignalRQueryStringAuthMiddleware
{
private readonly RequestDelegate _next;
public SignalRQueryStringAuthMiddleware(RequestDelegate next)
{
_next = next;
}
// Convert incomming qs auth token to a Authorization header so the rest of the chain
// can authorize the request correctly
public async Task Invoke(HttpContext context)
{
if (context.Request.Query.TryGetValue("A5S0kT0k", out var token))
{
context.Request.Headers.Add("Authorization", "Bearer " + token.First());
}
await _next.Invoke(context);
}
}
我可以看到我的中间件正在按预期执行并附加了正确的授权 Header。
然而,在我的启动过程中,我的授权似乎从未被调用,它直接移动到连接到 websocket'
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(cfg => {
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.Events = new JwtBearerEvents
{
OnMessageReceived = async (ctx) =>
{
Console.WriteLine(ctx.Token);
},
OnTokenValidated = async (ctx) =>
{
Console.WriteLine("BreakPoint");
},
OnAuthenticationFailed = async (ctx) =>
{
Console.WriteLine("Breakpoint");
}
};
cfg.TokenValidationParameters = tokenValidationParameters;
});
这是我的管道在配置中的执行顺序
app.UseSignalRQueryStringAuth();
app.UseAuthentication();
app.UseSignalR(routes =>
{
routes.MapHub<DefaultServiceHubBase<MessageDTO>>("/messages");
routes.MapHub<DefaultServiceHubBase<ConversationDTO>>("/conversations");
routes.MapHub<InMemoryHub<UserLocationDTO>>("/user-locations");
});
我配置我的管道,以便首先命中中间件,但我永远无法命中 JWTBearer 部分中的任何断点的身份验证,但是,如果我制作标准的 HttpRequest,一切正常吗?
我的 OnMessageReceived
被忽略了,它直接转到我中心的 onconnect 函数 为什么会这样?
不知道为什么,但事实证明我还需要添加一个默认的挑战模式
services.AddAuthentication(options =>
{
// Identity made Cookie authentication the default.
// However, we want JWT Bearer Auth to be the default.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
中找到了这个