How to get OpenId Connect Configuration from ./well-known/openid-connect URL in OWIN?

I am migrating legacy ASP.Net application to support OpenId Connect Authentication with Keycloak Identity Provider. For this i have used OWIN OpenId Middleware and it works, but now I require to implement session management.

Keycloak offer its by using check_session_iframe endpoint, its url resides on OpenId Configuration in uri: http://192.168.99.100:8180/auth/realms/[realm_name]/.well-known/openid-configuration

I know that OWIN OpenId Middleware use OpenIdConnectAuthenticationOptions which contains property Configuration of type OpenIdConnectConfiguration where an equivalent of .well-known/openid-configuration file is parsed during Authentication flow.

It is possible to retrieve the Configuration from Controller or view to get OpenId connect url endpoints?

This is for ASP.Net MVC 5 application. For now i think one way is retrieve .well-known/openid-configuration directly using Authority Url, and set manually Configuration property.

Upvotes: 3

Views: 3927

Answers (2)

Steve P
Steve P

Reputation: 19377

One approach is to attach this information as a claim to the user's identity when it is created by the middleware.

1 - Specify a SecurityTokenValidated event in the options:

var options = new OpenIdConnectAuthenticationOptions
{
// snip
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = OnSecurityTokenValidated,
    }
};

2 - In that function, use the ConfigurationManager property of the notification options to get the current configuration. It handles cache and refresh behavior so that you don't have a make an extra request:

private async Task OnSecurityTokenValidated( SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification )
{
    var ticketIdentity = notification.AuthenticationTicket.Identity;
    var newIdentity = new ClaimsIdentity( ticketIdentity.Claims, ticketIdentity.AuthenticationType );

    if ( notification?.Options?.ConfigurationManager != null )
    {
        var cancelConfig = new CancellationTokenSource();
        cancelConfig.CancelAfter( TimeSpan.FromSeconds( 30 ) );

        var metadata = await notification.Options.ConfigurationManager.GetConfigurationAsync( cancelConfig.Token );

        newIdentity.AddClaim( new System.Security.Claims.Claim( "session_iframe_url", metadata.CheckSessionIframe ) );
    }

    notification.AuthenticationTicket = new AuthenticationTicket( newIdentity, notification.AuthenticationTicket.Properties );
}

Upvotes: 1

denyo85
denyo85

Reputation: 79

I had the same problem and couldn't find a way to read the configuration in a controller.

I only wanted to get the token endpoint URL without an extra request to the metadata endpoint because the OIDC middleware had already done that job!

Finally I used an extension method from the IdentityModel library to get the metadata (sadly with an extra metadata request):

var disco = await new HttpClient().GetDiscoveryDocumentAsync("http://localhost:8080/realms/mytenant");

Upvotes: 1

Related Questions