AD FS 2.0-Authentifizierung und AJAX
Ich habe eine Website, die Sie versuchen zu nennen eine MVC-controller-action auf einer anderen Website. Diese Seiten sind sowohl das setup als relying party Vertrauensstellungen in AD FS 2.0. Alles authentifiziert und funktioniert einwandfrei beim öffnen von Seiten im browser-Fenster zwischen den beiden Standorten. Jedoch, wenn Sie versuchen, Aufruf einer controller-action von JavaScript mit dem jQuery-AJAX-Methode es schlägt immer fehl. Hier ist ein code-snippet, was ich versuche zu tun...
$.ajax({
url: "relyingPartySite/Controller/Action",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
//do something here
},
error: function (data, status) {
alert(status);
}
});
Das Problem ist, dass AD FS verwendet JavaScript, um post ein verstecktes html-Formular an die relying party.
Bei der Ablaufverfolgung mit Fiddler kann ich sehen, es zu erhalten, um die AD FS-Website und senden Sie diese html-Formular sollte die post und leiten Sie an die controller-action authentifiziert. Das problem ist, diese form kommt zurück als Ergebnis der ajax-Anfrage und offensichtlich zum scheitern verurteilt mit einem parser-Fehler, da der ajax request erwartet json aus der controller-action. Wie es scheint, wäre dies ein häufiges Szenario, also, was ist der richtige Weg, um die Kommunikation mit AD FS von AJAX und Griff diese Umleitung?
- wenn die HTML zurückgegeben wird von der ajax-Aufruf, klar Sie wollen nicht analysieren, es mit dem json-parser. ändern Sie Datentyp "html", und die post-ein Beispiel für den html zurückgegeben, so kann ich Ihnen zeigen, wie Sie eine Prozedur schreiben, legt zurück.
- Das Problem ist, ich will zurück zu erhalten, JSON. AD FS leitet mit einer neuen HTML-form posten möchte zum durchführen der handshake, die es braucht. Dies funktioniert sehr gut, innerhalb eines browser-Fensters aber nicht hier. Sobald der handshake passiert, gibt es keinen redirect mit der AJAX-Anfrage und ich wieder JSON. Ich habe einen workaround für jetzt behandeln die html-Seite post in einem IFRAME, aber es ist nicht ideal.
- Ich verstehe, dass Sie wollen, um wieder JSON, aber du wirst es nicht zurück bekommen, JSON. Jedoch, wenn Sie wollen in der Lage sein zu behandeln, die zurückgegeben Datenstruktur, als ob es waren JSON -, post-ein Beispiel für den HTML zurückgegeben, und ich werde Ihnen zeigen, wie Sie eine Prozedur schreiben, legt zurück ohne mit einem IFRAME.
- Warum in meinem Fall gab er mir die Fehlermeldung "Kein access-control-Allow-Access-Allow-Origin'? Es ist ein CORS-problem, das heißt, mein browser verhindert das umleiten auf meinem ADFS-server, weshalb Ihre Anfrage umgeleitet werden kann, um die ADFS-server?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie zwei Möglichkeiten.
Mehr info hier.
Den ersten teilen ein session-cookie zwischen einem entry-Anwendung (eine, die ist HTML-basiert) und Ihren API-Lösungen. Sie konfigurieren beide Anwendungen verwenden die gleiche WIF-cookie. Dies funktioniert nur, wenn beide Anwendungen auf dem gleichen root-Domäne.
Siehe oben den post oder das stackoverflow-Frage.
Die andere Möglichkeit ist das deaktivieren der passiveRedirect für AJAX-Anfragen, die (wie Gutek Antwort). Dies wird return ein http-status-code 401, die Sie behandeln können, die in Javascript.
Wenn Sie feststellen, dass die 401, laden Sie eine dummy-Seite (oder eine "Authentifizierung" - dialog, die verdoppeln könnte, als login-dialog, wenn Anmeldeinformationen müssen wieder gegeben werden) in einem iFrame. Wenn die iFrame-abgeschlossen hat Sie dann versucht, den Anruf erneut. Diese Zeit der session-cookie wird anwesend sein auf den Anruf, und es sollte gelingen.
Wenn Sie nicht wollen, zu erhalten-HTML mit dem link, den Sie verarbeiten kann
AuthorizationFailed
aufWSFederationAuthenticationModule
- und set -RedirectToIdentityProvider
zufalse
auf Ajax-Aufrufe nur.Beispiel:
Diese mit
Authorize
Attribut zurück, die Sie status-code401
- und wenn Sie wollen etwas anderes, dann können Sie implementieren die eigenenAuthorize
Attribut und schreiben spezielle code auf Ajax-Request.Application_Start()
Methode derGlobal.asax.cs
- aber nicht. Es wird jedoch nur gut funktionieren, inApplication_BeginRequest()
.Das Projekt, an dem ich derzeit arbeite, hatten wir das gleiche Problem mit SAML-token Ablauf der clientseitigen und verursacht Probleme mit ajax-calls. In unserem speziellen Fall, wir brauchten alle Anfragen werden enqueud nach dem ersten 401 ist aufgetreten, und nach der erfolgreichen Authentifizierung werden alle von Ihnen könnten sich ärgern. Die Authentifizierung nutzt die iframe-Lösung vorgeschlagen, die von Adam Mills, aber geht auch ein wenig weiter, im Falle dass Benutzer Anmeldeinformationen eingegeben werden müssen, was getan wird, durch die Anzeige ein Dialogfeld informiert den Benutzer, der zur Anmeldung auf eine externe Sicht (seit ADFS nicht zulassen Anzeige der login-Seite in einem iframe atleast nicht-default-Konfiguration), während der warte-Wunsch warten beendet zu werden, aber der Benutzer muss einloggen auf von einer externen Seite. Die wartenden Anfragen auch abgelehnt werden, wenn der Benutzer wählt, um Abzubrechen und in den Fällen, jquery-Fehler aufgerufen wird, werden für jede Anfrage.
Hier ist ein link zu einer Zusammenfassung mit dem Beispiel-code:
https://gist.github.com/kaveh82/bb0d8e4a446496a6c05a
Hinweis mein code basiert auf der Verwendung von jquery für den Umgang mit allen ajax-request. Wenn Ihre ajax-request erfolgt durch Vanille javascript, anderen Bibliotheken oder frameworks, dann können Sie vielleicht finden Sie Ihre inspiration in diesem Beispiel. Die Verwendung von jquery ui ist nur, weil der dialog und steht für einen kleinen Teil von dem code, der konnte leicht ausgetauscht werden.
Zuerst sagen Sie, dass Sie versuchen zu machen eine ajax-Aufruf anderen website, ist Ihr Aufruf entspricht same-origin-policy von web-Browsern? Wenn es dann funktioniert, erwarten Sie, dass html als Antwort von Ihrem server, den Sie ändern
datatype
von der ajax-Aufruf zudataType: "html"
, dann legen Sie die form in Ihrem DOM.Vielleicht die 2 ersten posts von diese serie wird Ihnen helfen. Sie betrachten ADFS und AJAX-Anfragen
Was ich denke, ich würde versuchen zu tun ist, um zu sehen, warum die Authentifizierungs-cookies nicht übertragen werden durch ajax, und finde einen Mittelwert, um Sie zu senden mit meiner Anfrage. Oder wickeln Sie den ajax-Aufruf in einer Funktion, die pre-Authentifizierung abrufen der html-Formular, mit dem anfügen, es versteckt um den DOM, die Einreichung (es werden hoffentlich setzen sich die guten cookies), dann schickt die entsprechende Anfrage, die Sie senden wollten ursprünglich
Können Sie nur tun, diese Art von Datentyp
Wenn Sie sehen können, in Ihrem fiddler, die Rückkehr ist nur html ändern Sie dann Ihre Daten geben Sie in das html-oder wenn das nur ein script-code, dann können Sie Skript verwenden.
Erstellen Sie eine Datei anyname wie json.php und dann stellen Sie die Verbindung zum relayparty website sollte dies funktioniert
$.ajax({
url: "json.php",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
//do something here
},
error: function (data, status) {
alert(status);
}
});