2015-11-11 10 views
6

In meiner Implementierung Ich bin mit OpenID-Connect-Server (Identity Server v3 +) Asp.net MVC 5 app (mit AngularJS Front-End)OWIN-Middleware für OpenID Connect - Dokumentation zum Code-Flow (Flow-Typ - AuthorizationCode)?

Ich plane verwenden OID-Code-Flow (mit Scope Open_ID) zu authentifizieren authentifizieren Sie den Client (RP). Für die OpenID Connect Middleware verwende ich OWIN (Katana Project) Komponenten.

Vor der Implementierung möchte ich Back-Channel-Token-Anfrage, Aktualisierung Token-Anfrage-Prozess, etc. mit OWIN verstehen .. Aber ich kann keine Dokumentation für diese Art der Implementierung finden (die meisten verfügbaren Beispiele verwenden Implizite Strömung).

Ich konnte Proben für generische Code Flow Implementierung finden hier für ID Server v3 https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source

ich für ein ähnliches suchen Middleware OWIN? Hat jemand irgendwelche Hinweise?

Antwort

17

Die OpenID Connect-Middleware unterstützt den Code-Fluss nicht: http://katanaproject.codeplex.com/workitem/247 (es ist jedoch bereits in der ASP.NET 5-Version behoben).

Tatsächlich wird nur der implizite Fluss (id_token) offiziell unterstützt, und Sie müssen die response_mode=form_post Erweiterung verwenden. Der Versuch, den Autorisierungscodefluss zu verwenden, führt einfach dazu, dass während des Rückrufs eine Ausnahme ausgelöst wird, da die (fehlende) id_token aus der Authentifizierungsantwort nicht extrahiert werden kann.

Obwohl nicht direkt unterstützt, können Sie auch den hybriden Fluss (code + id_token (+ token)) verwenden, es liegt jedoch an Ihnen, den Token-Anforderungsteil zu implementieren. Sie können https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Nancy/Nancy.Client/Startup.cs#L82-L115 für ein Beispiel sehen.

+3

So viel Wissen verpackt in diese Antwort. Es muss dir Zeit genommen haben, all diese Schmerzpunkte zu entdecken. Erweiterung auf * Exception, die während des Callbacks * für das OP ausgelöst wird: Die Ausnahme liegt an einem ID-Token, das beim Aufruf von idsvr nicht zurückgegeben wird, wenn Sie nur nach 'code' flow fragen (was natürlich beabsichtigt ist). –

+1

@CrescentFresh danke das freundliche Wort! Tatsächlich habe ich ein paar Mal zur OIDC-Middleware beigetragen (zum Beispiel habe ich die Unterstützung von response_mode = query eingeführt) und entwickle das Server-Pendant für OWIN/Katana und ASP.NET 5 (https://github.com/aspnet) -contrib/AspNet.Security.OpenIdConnect.Server), was erklärt, warum ich mich mit den Fragen in Bezug auf OIDC wohl fühle;) Ich habe meine Antwort aktualisiert, um Ihre Präzision zu berücksichtigen, danke! – Pinpoint

+0

Können Sie mir bitte bei dieser Frage helfen: https: //stackoverflow.com/questions/47096113/token-based-implementation-in-webapi-to-secure-endpoints –

0

Die Antwort und Kommentar Antworten von Pinpoint sind genau richtig. Vielen Dank!

Wenn Sie jedoch bereit sind, vom NuGet-Paket abzuweichen und stattdessen den modifizierten Quellcode für Microsoft.Owin.Security.OpenIdConnect auszuführen, können Sie Code (code) mit form_post senden.

Natürlich kann dies für alle Open-Source-Projekt Probleme gesagt werden, aber dies war eine schnelle Lösung für eine große Sache in meinem Fall, so dachte ich, ich würde es könnte eine Option sein.

Ich habe Code von https://github.com/aspnet/AspNetKatana heruntergeladen, fügte der Lösung csproj hinzu und entfernte die Zeilen von https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs in AuthenticateCoreAsync().

Sie müssen es dann mit Backchannel-Aufrufen kombinieren und dann Ihre eigene neue ClaimsIdentity() erstellen, die als notification.AuthenticationTicket festgelegt wird.

// 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; 
    } 
    ..