ASP.NET Core MVC OpenIdConnect how do I check if HttpContext.SignOutAsync is allowed?

Viewed 99

I'm using OpenIdConnect with Auth0 (via the Microsoft.Identity.Web package) and the call to HttpContext.SignOutAsync(..) fails with an error

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

This is expected because Auth0's well known configuration does not publish a signout endpoint (which is a bit funky given how hard they push their book on OAuth).

I'm trying to figure out how, if at all, I can get the current OpenIdConnect configuration settings that were loaded from the well known endpoint. I'd like to check for myself if the signout endpoint exists instead of eating the exception.

Plus from a logging/debugging/supporting a raft of other providers I really would like to get the well known settings currently loaded. For example I'm expecting at some point to have to support Broadcom's SiteMinder... which if past experience has taught me anything is going to involve sufficient logging such that I can pass the problem over to my client's technical folks (to either fix or take up with SiteMinder people).

Thanks

1 Answers

The most standard option is for the OpenID Connect metadata to include an end_session_endpoint. When that is missing you will get the above .NET error by default.

RP Initiated Logout is a draft specification, and some providers have custom implementations. This post discusses Auth0's behaviour, and you will need to build a custom logout URL.

In .NET you can use Events to resolve your issues, and you will need code similar to the following - from this previous answer.

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
  Authority = ...
  ClientId = ...
  Events = new OpenIdConnectEvents()
  {
    OnRedirectToIdentityProviderForSignOut = context =>
    {
      context.IssuerAddress = myAuth0CustomLogoutUrl;
    }
  }
});

The above context also has an Options object that you can use to get the metadata, via its ConfigurationManager property.

Alternatively you can get metadata like this outside of event handlers. This will allow you to detect if the downloaded metadata contains an end session endpoint.

var url = $"{authorityUrl}/.well-known/openid-configuration";
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(url, new OpenIdConnectConfigurationRetriever());
var config = await configManager.GetConfigurationAsync().ConfigureAwait(false);
if (String.IsNullOrWhiteSpace(config.EndSessionEndpoint))
{
  // Do something
}

A more elegant option might be to register the OpenIdConnectOptions object as a singleton, then inject it into the logout controller. You can then access the exact ConfigurationManager instance that the infrastructure is using:

services.AddSingleton(options);

class LogoutController
{
  public LogoutController(OpenIdConnectOptions options)
  {
  }

  public SomeMethod()
  {
    // Use options
  }
}

You can put any custom logging either in the above handler or in OnMessageReceived, which will also fire whenever an OIDC message is received - eg metadata is downloaded.

Related