2014-01-22 11 views
35

Ich bin völlig neu in der OWIN-Authentifizierung, und ich muss falsch verstehen, wie alles funktioniert, aber ich kann das nirgendwo erwähnt finden.Login-Seite auf andere Domäne

Alles, was ich will, ist in der Lage sein, eine zentrale Domäne für die Authentifizierung zu verwenden. Wenn jemand versucht, auf apps.domain.com zuzugreifen, wenn er nicht authentifiziert ist, wird er an accounts.domain.com/login weitergeleitet, so dass die gesamte Authentifizierung in seine eigene Domäne und Anwendung getrennt ist. Dies war sehr einfach mit MVC 4 Formularauthentifizierung, wo Sie eine vollständige URL angeben können, aber nicht mit OWIN zu sein scheint.

In Startup.Auth.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    LoginPath = new PathString("/account/login") 
} 

Es ist einfach, die Domäne angeben, wenn das Cookie mit der Option CookieDomain Einstellung. Wenn Sie jedoch den Anmeldepfad angeben, zu dem umgeleitet werden soll, muss er relativ zur aktuellen Anwendung sein. Wie gehe ich also vor, was bei der MVC 4-Formularauthentifizierung so einfach war?

Ohne zu tief in die OWIN-Authentifizierung zu gehen, konnte ich nach ein paar Stunden Suche nichts finden, was dies angeht.

Antwort

42
public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationMode = AuthenticationMode.Active, 
      LoginPath = new PathString("/account/login"), 
      LogoutPath = new PathString("/account/logout"), 
      Provider = new CookieAuthenticationProvider 
      { 
       OnApplyRedirect = ApplyRedirect 
      }, 
     }); 
    } 

    private static void ApplyRedirect(CookieApplyRedirectContext context) 
    { 
     Uri absoluteUri; 
     if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri)) 
     { 
      var path = PathString.FromUriComponent(absoluteUri); 
      if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath) 
      { 
       context.RedirectUri = "http://accounts.domain.com/login" + 
        new QueryString(
         context.Options.ReturnUrlParameter, 
         context.Request.Uri.AbsoluteUri); 
      } 
     } 

     context.Response.Redirect(context.RedirectUri); 
    } 
} 

Wenn apps.domain.com die einzige Rückkehr URL Basis möglich ist, sollten Sie in Erwägung ziehen, context.Request.Uri.AbsoluteUri mit context.Request.PathBase + context.Request.Path + context.Request.QueryString und bauen eine absolute Rendite URL in Ihrem Authentifizierungsserver ersetzen, um Ihre Anwendungen vor missbräuchlichen Umleitungen zu schützen.

this helps;)

EDIT: Sie könnten sich fragen, warum ich nicht direkt die Umleitung gelten die context.RedirectUri Eigenschaft. Tatsächlich ist ICookieAuthenticationProvider.ApplyRedirect für mehrere Umleitungen verantwortlich, die den An- und Abmeldeströmen entsprechen (ja, ich weiß, es bricht das Prinzip der einheitlichen Verantwortlichkeit ...). Aber es gibt noch schlimmer: context.RedirectUri kann entweder die absolute URL des Authentifizierungsendpunkts am Anfang des Anmeldevorgangs oder das Ziel des endgültigen Browsers (dh die echte relative "Rücksprung-URL") darstellen, wenn der Cookie tatsächlich zurück an den Browser gesendet wird ... deshalb müssen wir sicherstellen, dass context.RedirectUri absolut ist und dem registrierten context.Options.LoginPath entspricht.

+0

Vielen Dank für die Antwort! Es sieht gut aus, ich werde es ausprobieren, wenn ich heute Abend nach Hause komme. –

+0

Dank Tracher habe ich einen kleinen Fehler behoben, der verhinderte, dass dieser Fehler bei der Verwendung einer PathBase (über app.Map zum Beispiel) funktioniert.Bitte beachten Sie den aktualisierten Code. – Pinpoint

+0

Funktioniert wie ein Zauber, danke nochmal :) –

3

Ich arbeite durch die Beispiele für https://github.com/IdentityServer/IdentityServer3 und ich habe eine andere Antwort. Im Beispiel unter https://www.scottbrady91.com/Identity-Server/Identity-Server-3-Standalone-Implementation-Part-2 zeigen sie eine MVC-App, die eine eigenständige IdP und Cookies-Authentifizierung verwendet. Das Beispiel hat nicht 401 Redirects funktioniert, aber ich stolperte über einen Weg.

Das grundlegende Schema besteht darin, eine Aktion im AccountController für die Anmeldung zu erstellen.

public ActionResult SignIn() { 
    // set up some bookkeeping and construct the URL to the central auth service 
    return Redirect(authURL); 
} 

Jetzt haben Sie eine lokale URL, die in dem Autostart verwendet werden können

public class Startup { 
    public void Configuration(IAppBuilder app) { 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "Cookies", 
     LoginPath = new PathString("/Account/SignIn") 
    }); 
} 

Sie haben auch den zusätzlichen Vorteil, dass Sie eine Aktion Link zum SignIn in der Menüleiste setzen, für die Menschen die sich anmelden möchten, bevor es eine 401 gibt. Was wir hier getan haben, ist die Entkoppelung der Entscheidung, was zu tun ist, wenn ein nicht authentifizierter Benutzer nach einer Ressource fragt, wie die Authentifizierung erhalten wird.

+0

genannt werden Ich bevorzuge diese Lösung viel lieber, weil sie das Framework wie beabsichtigt verwendet, anstatt ApplyRedirect mit benutzerdefinierter Logik zu überschreiben. – infl3x

Verwandte Themen