2017-10-19 3 views
0

Ich arbeite mit einer MVC5-Anwendung, die durch die OWIN-Komponenten WsFederationAuthentication und CookieAuthentication gesichert ist. Als Teil des Anmeldeprozesses injiziere ich einige zusätzliche Ansprüche in die ClaimsIdentity, die vom SAML-Provider (in diesem Fall ADFS) während des OnResponseSignIn Delegierten eines CookieAuthenticationProvider zurückgegeben wird, wenn ich CookieAuthenticationOptions während des Startvorgangs einstelle. Dadurch kann ich die ClaimsIdentity im OwinContext bearbeiten, bevor sie zum Generieren des Tickets verwendet wird. In der Praxis funktioniert das gut für das, was ich in der Vergangenheit tun musste (meist werden benutzerdefinierte Ansprüche hinzugefügt, die von Werten abhängen, die in einer Datenbank gefunden werden, die mit Daten übereinstimmt, die von dem eingehenden Anspruch geliefert werden).Eine ansonsten erfolgreiche ws-Verbund-Anmeldung in einem CookieAuthenticationProvider() ablehnen

Abhängig von Umständen, die auftreten, wenn OnResponseSignIn ausgeführt wird, muss ich nun in der Lage sein, die Anmeldung so abzulehnen, dass ich dem Benutzer einen Fehler anzeigen kann, der angibt, warum sie sich nicht anmelden können. Das erweist sich als viel schwieriger, als ich es mir vorgestellt habe.

Dies sind die beiden wichtigsten Ansätze, die ich versucht habe:

  1. eine Ausnahme in CookieAuthenticationProvider.OnResponseSignIn Wurf:
    Dies funktioniert, dass das Authentifizierungscookie wird Fänge nie gesetzt und meine globalen Fehlerhandler die Ausnahme und zeigt sie dem Benutzer an. Ich kann jedoch keinen Weg finden, die Identität effektiv abzulehnen, bevor die Ausnahme ausgelöst wird. Also glaubt mein globaler Fehlerhandler, dass der HttpContext authentifiziert ist und rendert die Fehleransicht mit Elementen, die nicht gerendert werden sollten, wenn der Benutzer nicht authentifiziert ist. Das Nullen der OwinContext.Identity in OnResponseSignIn hat keinen Effekt, da ich nur einen Wert innerhalb des OnResponseSignInContext lösche, der keine Auswirkung auf die gesamte Pipeline hat. Soweit ich weiß, kann ich die tatsächliche ClaimsIdentity selbst nicht als authentifiziert markieren, da IsAuthenticated auf true gesetzt ist, wenn Sie den Authentifizierungstyp im ClaimsIdentity ctor festlegen und danach nicht mehr geändert werden können.

  2. einen „Fehler“ Anspruch in CookieAuthenticationProvider.OnResponseSignIn als Brotkrümel hinzufügen und dann für sie in CookieAuthenticationProvider.OnValidateIdentity aussehen und die Ausnahme dort werfen.
    Dieser Ansatz hat den Vorteil, die Anmeldung löschen zu können (ein Vorteil, der von OnValidateIdentityContext.RejectIdentity() geboten wird). Jetzt wird meine Fehleransicht für einen nicht authentifizierten Benutzer korrekt dargestellt. Das Problem hierbei ist jedoch, dass ich keine Möglichkeit finde, zu verhindern, dass das Authentifizierungscookie, das nach OnResponseSignIn erstellt wurde, an den Client gesendet und im Browser festgelegt wird. Die Tools, die ich in diesen Delegierten zur Verfügung habe, ermöglichen es mir, Cookies von der OwinContext anzufügen und zu löschen, aber irgendwie ist dieser Cookie nicht einer, mit dem ich das machen kann. Es scheint tatsächlich zu dem Antwortstream später in der Pipeline hinzugefügt zu werden, wo ich es nicht ändern kann. Also, wenn ich OnResponseSignIn abschließen lasse und dann nach dem Cookie während der Ausführung von OnResponseSignedIn suche, sehe ich es dort nicht. Wirklich nicht sicher, warum das ist - Blick auf die Quelle von CookieAuthenticationHandler, es sieht aus wie ich dachte, ich sollte es sehen, wie es zwischen der Ausführung dieser beiden CookieAuthenticationProvider Delegierten hinzugefügt wird. Ich kann auch nicht verhindern, dass der Cookie überhaupt erzeugt wird, da der CookieAuthenticationHandler eine Ausnahme auslöst, wenn das Ticket nicht serialisiert werden kann.

Also, ich kann entweder keine Cookie-Gruppe erhalten und ein As-if-authentifizierte Fehleransicht oder eine nicht authentifizierte Fehleransicht, aber ein Cookie gesetzt haben, die effektiv den Benutzer daran hindert, versucht sich erneut anmelden.

Letztendlich rolle ich im Schlamm des Rahmens genug an diesem Punkt, ich fühle mich wie ich muss das Problem falsch nähern.Eine Antwort auf diese Frage lautet:

Wie kann ich ein ansonsten gültiges WsFederation-Authentifizierungspostback ablehnen und einem Benutzer einen Fehler anzeigen, der erklärt, was passiert ist, ohne ein AuthenticationTicket an den Client zu senden?

Ich vermute, dass es einen anderen Punkt im Prozess geben muss (vielleicht nicht in CookieAuthenticationProvider), wo dies getan werden kann, bevor die Pipeline entscheidet, dass die Authentifizierung erfolgreich war.

+0

Zu meiner (hoffentlich) vorläufigen Lösung gehört die Verwendung eines Tests für einen Anspruch, den ich während 'OnResponseSignIn' hinzufüge, um festzustellen, ob ein Benutzer tatsächlich angemeldet ist (im Gegensatz zu' Request.IsAuthenticated'). Hässlich, aber es funktioniert. –

Antwort

1

Wahrscheinlich verwenden Sie so etwas wie dies in Ihrem Startup-Code:

app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()) 

Die Klasse WsFederationAuthenticationOptions bietet die Möglichkeit, in die wsfed Authentifizierung (wie die CookieAuthenticationProvider für den Cookie-Authentifizierung) einzuhaken. Sie können die Notifications-Eigenschaft auf eine neue Instanz von WsFederationAuthenticationNotifications festlegen. Ich empfehle, die Eigenschaft SecurityTokenValidated zu verwenden und sie auf Ihre Implementierung zu setzen, d. H. Eine neue Methode, die der erforderlichen Func<> Definition entspricht. Dies ist der Punkt, nachdem das Token die Validierung bestanden hat und eine ClaimsIdentity generiert wurde. Dann können Sie Ihre zusätzlichen Prüfungen durchführen und den AuthenticationTicket des Methodenparameters SecurityTokenValidatedNotification auf null setzen und die HttpResponse ändern. Dann sollte der CookieAuthenticationHandler nicht ausgelöst werden.

+0

Ah! Das sieht sehr vielversprechend aus! Ich konnte nicht herausfinden, wie man den WsFed-Stack erweitert. Ich nahm an, dass es einen Weg gab, aber ich hatte Probleme, gute Beispiele oder Dokumentationen zu finden. Das ist sehr hilfreich. Wenn ich Zeit habe, das zu wiederholen und umzusetzen, werde ich es versuchen und meine Erfahrung hinzufügen. In der Zwischenzeit werde ich die Antwort akzeptieren. –

Verwandte Themen