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:
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.einen „Fehler“ Anspruch in
CookieAuthenticationProvider.OnResponseSignIn
als Brotkrümel hinzufügen und dann für sie inCookieAuthenticationProvider.OnValidateIdentity
aussehen und die Ausnahme dort werfen.
Dieser Ansatz hat den Vorteil, die Anmeldung löschen zu können (ein Vorteil, der vonOnValidateIdentityContext.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 nachOnResponseSignIn
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 derOwinContext
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 ichOnResponseSignIn
abschließen lasse und dann nach dem Cookie während der Ausführung vonOnResponseSignedIn
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 beidenCookieAuthenticationProvider
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.
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. –