15. September 2015 · von Steffen Nörtershäuser

ADFS Handshake mit Ionic

In einem aktuellen Projekt stellte sich die Herausforderung, per Ionic Daten von einem Webservice abzufragen, welcher in einem SharePoint hinter einem ADFS (Active Directory Federation Services) gehosted wurde. Hierbei gab es für uns zwei Möglichkeiten:

  • Den Anwender auf die ADFS Seite umzuleiten, wo er die Credentials eingeben kann
  • Eine eigene Login Maske sowie den dahinter liegenden ADFS Handshake

Da die ADFS Login Maske auf einem Handy schwer zu bedienen war, und es Probleme gab, die Credentials des Nutzers langfristig zu speichern, haben wir uns für eine eigene Login Maske und den dazugehörigen ADFS Handshake entschieden.

Ablauf des ADFS Handshake

Der ADFS Handshake gliedert sich im Groben in folgende Schritte:

  1. Anfrage an den SharePoint Webservice. Dieser antwortet mit Access Denied und leitet auf die ADFS Url um.
  2. Senden der Credentials an den ADFS Server. Dieser sendet ein ADFS Token Cookie als Antwort.
  3. Per ADFS Token einen SharePoint Federation Token Cookie ermitteln.
  4. Mit diesem SharePoint Federation Token Cookie ist man nun gegen den SharePoint Server authentifiziert.

Nachdem das SharePoint Cookie gesetzt wurde, kann man in Ionic auf alle SharePoint Inhalte zugreifen. Auch ist es möglich, den Browser des Handys zu nutzen, um SharePoint Seiten darzustellen. Durch das Cookie muss sich der Nutzer nicht erneut anmelden, wenn er SharePoint Seiten öffnet.

Implementierung mit Ionic und AngularJS

Da ich mich in diesem Artikel auf den ADFS Handshake konzentrieren möchte, werde ich nicht auf das Whitelisting von SharePoint und ADFS Urls eingehen und setze dieses voraus.

Wie oben erwähnt ist der erste Schritt die Ermittlung der ADFS Url:

var adfsBaseUrl = "https://adfs.sample.com";
$http.get(sharePointUrl).success(function (data, status, headers, config) {
    var pseudoDom = angular.element(data);
    var elements = pseudoDom.find("form");
    var actionurl = "";

    for (var count = 0; count < elements.length; ++count) {
        if (elements[count].id == "loginForm") {
            actionurl = elements[count].action;

            // Da durch Ionic und AngularJS das "file://" Protokoll einfügt muss dieses hier entfernt werden
            actionurl = adfsBaseUrl + actionurl.replace("file://", "");
        }
    }

    // ...
});

Nach dieser Anfrage beinhaltet die Variable „actionurl“ die Url des ADFS Servers. Der nächste Schritt ist das Senden der Credentials:

$http.post(actionurl, "UserName=" + encodeURIComponent(loginName) + "&Password=" + encodeURIComponent(password) + "&AuthMethod=FormsAuthentication").success(function (fedAuthdata, status, headers, config) {
   // ...
});

Wie zu sehen ist, müssen hier lediglich die Logindaten des Nutzers als POST Nachricht an den ADFS Server geschickt werden.

Bei korrekten Credentials antwortet der ADFS Server mit einem HTML Formular, welches die Anfrage für den SharePoint Federation Token beinhaltet. Diese wird bei einer Browser Anfrage per JavaScript automatisch geposted. Da wir in dem Beispiel für das Formular jedoch keinen Browser öffnen, müssen wir es selbst in eine POST Anfrage konvertieren und absenden:

var newFakeDom = angular.element(fedAuthdata);

var action = "";
for (var curElem = 0; curElem < newFakeDom.length; ++curElem) {
    if (newFakeDom[curElem].tagName) {
        if (newFakeDom[curElem].tagName.toLowerCase() === "form") {
            action = newFakeDom[curElem].action;
        }
    }
}

if (action === "") {
    // Error Handling
    // ...
    return;
}

var inputs = newFakeDom.find("input");
var datastring = "";
for (var count = 0; count < inputs.length; ++count) {
    if (datastring) {
        datastring += "&";
    }
    var decoded = angular.element('<textarea />').html(inputs[count].value).text();

    datastring += inputs[count].name + "=" + encodeURIComponent(decoded);
}
                    

$http({
    method: 'POST',
    url: action,
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    data: datastring
})
.success(function (data, status, headers, config) {
    // Cookie ist gesetzt. Es kann nun auf den SharePoint zugegriffen werden.
    // ...
});

Nachdem diese HTTP Anfrage erfolgreich war, ist ein SharePoint Federation Cookie innerhalb der Ionic App gesetzt und es kann wie gewohnt über Angular HTTP Anfragen an einen SharePoint Webservice gesendet werden oder eine SharePoint Seite in einem IFrame oder mithilfe des In-App Browsers geöffnet werden.



Diesen Blogeintrag bewerten:

3 Stimmen mit durchschnittlich 3/5 Punkten

Haben Sie Fragen zu diesem Artikel oder brauchen Sie Unterstützung?

Nehmen Sie mit uns Kontakt auf!

Wir unterstützen Sie gerne bei Ihren SharePoint-Vorhaben!


Schreibe einen Kommentar

Kontakt.
Lassen Sie sich von uns beraten
Wir freuen uns über Ihr Interesse an unseren Leistungen. Hinterlassen Sie
uns Ihren Namen, Ihre Telefonnummer und E-Mail Adresse – wir melden
uns schnellstmöglich bei Ihnen.
Kontakt aufnehmen