Search code examples
identityserver4

Identity Server 4 GetSchemeSupportsSignOutAsync returns incorrect response


I've setup an open id connect provider, Google in this case, using the AddOpenIdConnect extension method in dotnet core. From the discovery document:

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

it does not seem that google supports federated sign-out because there is no end_session endpoint. However, in Identity Server 4, the call:

var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);

returns true. So during Logout it tries to sign out of google using:

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

which throws an exception:

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

Is this a bug in Identity Server 4 or is there a configuration property that needs to be set when setting up the Oidc provider so that this extension method will pickup that the provider does not support signout?


Solution

  • Doesn't appear to be a bug in Identity Server 4. The code behind this extension calls out to get the underlying authentication scheme handler.

        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);
        }
    

    In this case, your handler will be OpenIdConnectHandler which appears to implement IAuthenticationSignOutHandler so that's why regardless of what is in the discovery document (end session endpoint supported or not), if you use the AddOpenIdConnect(...), it will always register a handler which seemingly supports sign out, but as you have pointed out, does not actually enforce the actual idp validation for that kind of functionality support (link to handler source).

    And lastly, worthwhile to mention, that Identity Server 4 check is rightful here as according to Microsoft docs, the IAuthenticationSignOutHandler is indeed basically a marker interface used to determine if a handler supports SignOut.

    So I guess you just simply can't use the generic AddOpenIdConnect(...), instead perhaps you should use AddGoogle(...) which does not implement IAuthenticationSignOutHandler so will work as expected with Identity Server 4 (link to source).