13
votes

In my implementation I am using OpenID-Connect Server (Identity Server v3+) to authenticate Asp.net MVC 5 app (with AngularJS front-end)

I am planning to use OID Code flow (with Scope Open_ID) to authenticate the client (RP). For the OpenID connect middle-ware, I am using OWIN (Katana Project) components.

Before the implementation, I want to understand back-channel token request, refresh token request process, etc using OWIN.. But I am unable to find any documentation for this type of implementation (most of the available examples use Implicit flow).

I could find samples for generic Code flow implementation for ID Server v3 here https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source

I am looking for a similar one using OWIN middleware ? Does anyone have any pointers ?

2

2 Answers

32
votes

Edit: good news, code flow and response_mode=query support was finally added to Katana, as part of the 4.1 release (that shipped in November 2019): https://github.com/aspnet/AspNetKatana/wiki/Roadmap#410-release-november-2019.


The OpenID Connect middleware doesn't support the code flow: http://katanaproject.codeplex.com/workitem/247 (it's already fixed in the ASP.NET 5 version, though).

Actually, only the implicit flow (id_token) is officially supported, and you have to use the response_mode=form_post extension. Trying to use the authorization code flow will simply result in an exception being thrown during the callback, because it won't be able to extract the (missing) id_token from the authentication response.

Though not directly supported, you can also use the hybrid flow (code + id_token (+ token)), but it's up to you to implement the token request part. You can see https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Nancy/Nancy.Client/Startup.cs#L82-L115 for an example.

1
votes

The answer and comment replies by Pinpoint are spot on. Thanks!

But if you are willing to step away from the NuGet package and instead run modified source code for Microsoft.Owin.Security.OpenIdConnect you can get code (code) flow with form_post.

Of course this can be said for all open source project problems but this was an quick solution for a big thing in my case so I thought I'd share that it could be an option.

I downloaded code from https://github.com/aspnet/AspNetKatana, added the csproj to my solution and removed lines from https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs in AuthenticateCoreAsync().

You must then combine it with backchannel calls and then create your own new ClaimsIdentity() to set as the notification.AuthenticationTicket.

// Install-Package IdentityModel to handle the backchannel calls in a nicer fashion
AuthorizationCodeReceived = async notification =>
{
    var configuration = await notification.Options.ConfigurationManager
             .GetConfigurationAsync(notification.Request.CallCancelled);

    var tokenClient = new TokenClient(configuration.TokenEndpoint,
             notification.Options.ClientId, notification.Options.ClientSecret,
                  AuthenticationStyle.PostValues);
    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
        notification.ProtocolMessage.Code,
        "http://localhost:53004/signin-oidc",
        cancellationToken: notification.Request.CallCancelled);

    if (tokenResponse.IsError 
            || string.IsNullOrWhiteSpace(tokenResponse.AccessToken)
            || string.IsNullOrWhiteSpace(tokenResponse.RefreshToken))
    {
        notification.HandleResponse();
        notification.Response.Write("Error retrieving tokens.");
        return;
    }

    var userInfoClient = new UserInfoClient(configuration.UserInfoEndpoint);
    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

    if (userInfoResponse.IsError)
    {
        notification.HandleResponse();
        notification.Response.Write("Error retrieving user info.");
        return;
    }
    ..