使用 IdentityServer 承载的 SignalR 不会从 Hub 接收任何 JWTBearerEvents

Posted

技术标签:

【中文标题】使用 IdentityServer 承载的 SignalR 不会从 Hub 接收任何 JWTBearerEvents【英文标题】:SignalR using IdentityServer bearer won't receive any JWTBearerEvents from Hub 【发布时间】:2019-04-30 17:07:35 【问题描述】:

我们有一个 api (.net core 2.2),它使用 IdentityServerAuthenticationDefaults.AuthenticationScheme 用于所有可以正常工作的控制器。

我们现在决定为会议服务添加 SignalR Hub。 仅当我们删除授权属性 [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)] 时,集线器才能正常工作

我们确实尝试使用以下两种方法处理查询中的令牌(TokenRetriever 或 JwrBearerEvents)

services.AddAuthentication()
        .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
        
            options.Authority = AuthURL;
            options.SupportedTokens = SupportedTokens.Jwt;
            options.RequireHttpsMetadata = HttpsSetting;
            options.ApiName = APIs.API_Commerce;
            options.TokenRetriever = new Func<HttpRequest, string>(req =>
            
                var fromHeader = TokenRetrieval.FromAuthorizationHeader();
                var fromQuery = TokenRetrieval.FromQueryString();
                return fromHeader(req) ?? fromQuery(req);
            );
            options.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("/hubs/")))
                    
                        // Read the token out of the query string
                        context.Token = accessToken;
                    
                    return Task.CompletedTask;
                ;
        );

由于某种原因,这些论文仅在我们调用控制器但忽略所有从客户端调用的方法时触发。

请注意,我们有一个提供令牌和 API 的 AuthServer。 我们在客户端使用 angular 7 和 aspnet/signalr 模块。

【问题讨论】:

【参考方案1】:

我发现了问题...

    app.UseAuthentication() 被添加到配置中

    将默认方案添加到身份验证并删除 onmessagereceive ->

            services.AddAuthentication(options =>
        
            options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
        )
        .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
        
            options.Authority = AuthURL;
            options.SupportedTokens = SupportedTokens.Jwt;
            options.RequireHttpsMetadata = HttpsSetting;
            options.ApiName = APIs.API_Commerce;
            options.TokenRetriever = new Func<HttpRequest, string>(req =>
            
                var fromHeader = TokenRetrieval.FromAuthorizationHeader();
                var fromQuery = TokenRetrieval.FromQueryString();
                return fromHeader(req) ?? fromQuery(req);
            );
        );
    

提到 .net core 2.2 你必须指定一个来源 (withOrigins) 并且不能使用 Any..

【讨论】:

伙计,在过去的一个小时里,我一直在思考如何处理 SignalR 的令牌检索。感谢这个简单的解决方案! 最佳解决方案,谢谢! 你是救生员。一整天都在敲打头

以上是关于使用 IdentityServer 承载的 SignalR 不会从 Hub 接收任何 JWTBearerEvents的主要内容,如果未能解决你的问题,请参考以下文章

如何在流动客户端主题时在C#HttpClient中设置OIDC / OAuth承载令牌

对一个特定端点使用不同的授权,.net 核心

IdentityServer4 使用OpenID Connect添加用户身份验证

如何测试我的令牌是不是使用 IdentityServer4 刷新?

错误:尝试使用中毒的“SIG_OUTPUT_COMPARE0A”

如何使用 IdentityServer 4 实现 Windows 身份验证