首页 > 解决方案 > Identity Server 4 GetSchemeSupportsSignOutAsync 返回不正确的响应

问题描述

我已经使用 dotnet 核心中的 AddOpenIdConnect 扩展方法设置了一个开放 id 连接提供程序,在本例中为 Google。从发现文档中:

https://accounts.google.com/.well-known/openid-configuration 

谷歌似乎不支持联合注销,因为没有 end_session 端点。但是,在 Identity Server 4 中,调用:

var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);

返回真。因此,在注销期间,它会尝试使用以下方式退出谷歌:

return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);

抛出异常:

InvalidOperationException: Cannot redirect to the end session endpoint, the configuration may be missing or invalid.

这是 Identity Server 4 中的错误,还是在设置 Oidc 提供程序时需要设置配置属性,以便此扩展方法将获取提供程序不支持注销的情况?

标签: identityserver4

解决方案


似乎不是 Identity Server 4 中的错误。此扩展背后的代码调用以获取底层身份验证方案处理程序。

    public static async Task<bool> GetSchemeSupportsSignOutAsync(this HttpContext context, string scheme)
    {
        var provider = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
        var handler = await provider.GetHandlerAsync(context, scheme);
        return (handler != null && handler is IAuthenticationSignOutHandler);
    }

在这种情况下,您的处理程序将OpenIdConnectHandler似乎实现IAuthenticationSignOutHandler,这就是为什么无论发现文档中的内容(是否支持结束会话端点),如果您使用AddOpenIdConnect(...),它将始终注册一个看似支持注销的处理程序,但是正如您所指出的,实际上并没有为这种功能支持强制执行实际的 idp 验证(指向处理程序源的链接)。

最后,值得一提的是,根据Microsoft 文档,Identity Server 4 检查在这里是正确的,这IAuthenticationSignOutHandler实际上基本上是一个标记接口,用于确定处理程序是否支持 SignOut。

所以我猜你只是不能使用 generic AddOpenIdConnect(...),相反,也许你应该使用AddGoogle(...)which 没有实现IAuthenticationSignOutHandler,所以 Identity Server 4 将按预期工作(链接到源代码)。


推荐阅读