19. Februar 2018 · von Gate4 GmbH

Office 365 Login mit Electron

Wenn man plattformübergreifende Desktopapplikationen für Windows, Mac OS und Linux entwickeln möchte, dabei aber nicht drei unterschiedliche Quellcodes pflegen will, der kommt sehr schnell auf Electron. Electron bietet genau das: Ein Entwicklungsstand für drei verschiedene Desktop Systeme.

Electron ist im Grunde eine Kombination aus einem Node.Js Backend und einem Chromium-Engine Frontend. Auf dieser Basis kann man nun mit JavaScript, HTML und CSS Plattform übergreifende Apps entwickeln. Das Gute daran: Der Frontend-Code kann meist ohne große Veränderung auf eine Web-Plattform übernommen werden. Prominente Beispiele für Electron Apps sind z.B. Microsoft Visual Studio Code oder der Office 365 Teams Client.
Ich möchte hier nun zeigen, wie man sich in einer Electron App gegen ein Office 365 Authentifizieren kann, um dann zum Beispiel mittels eines REST-API Calls Daten vom SharePoint Online abzurufen.
Der O365 Authentifizierungs Mechanismus setzt auf ADAL, der Active Directory Authentication Library, auf. Hierzu muss zunächst die neue App beim O365, bzw. Azure Active Directory registriert werden.

Bei dieser App-Registrierung muss man dem Azure AD eine Callback URL angeben. Dies kann durchaus eine Localhost URL sein, denn diese wird später von ADAL benutzt um ein Authentication Token zu übermitteln.
Mit der Registrierung erhält man eine APP-ID. Anhand dieser App-ID wird später unsere App und der Authentifizierungsversuch identifiziert. Zu guter Letzt muss noch ein Authentifizierungs-Schlüssel, das ClientSecret, erstellt werden. Dieser Schlüssel wird in Microsoft Azure nur einmalig, nach der Erstellung, angezeigt und muss sofort kopiert und gesichert werden.
Die Backend-Komponente muss nun mit diesen Parametern initialisiert werden:
        var clientId = '220bxxxx-xxxxx-xxxx-xxxx-xxxxxxxxe2b3';      // App Id - GUID
        var clientSecret = '1Cyf ... 7P6c='                         // Client Secret
        var authorityHostUrl = 'https://login.windows.net';
        var tenant = 'foo.onmicrosoft.com';                         // Office 365 Tenant
        var authorityUrl = authorityHostUrl + '/' + tenant;
        var redirectUri = 'http://localhost:3000/getAToken';        // Callback URL
        var resource = 'https://foo.sharepoint.com';                // Resource welche von der App genutzt wird
        var templateAuthzUrl = 'https://login.windows.net/' +
            tenant +
            '/oauth2/authorize?response_type=code&client_id=' +
            clientId +
            '&redirect_uri=' +
            redirectUri +
            '&state=<state>&resource=' +
            resource;
Wichtig ist, das hierbei die richtige Resource-URL mitgegeben wird, also die URL welche später die REST API Calls der App empfängt und beantworten soll.
Die eigentliche Authentifizierung wird vom Node.Js Backend aus durchgeführt. Dazu wird vom Frontend aus auf eine Benutzereingabe (Button) reagiert und ein Login-Window geöffnet:
        var loginWindow;
        viewModel.authenticate = function() {
            loginWindow = window.open("http://localhost:3000/auth");            
        };
Die Node.Js Server Komponente setzt daraufhin ein „authstate“ Cookie und macht eine Umleitung (Redirect) auf die Office 365 Login Page. In dem Login-Popup erscheint so der Microsoft-Login Screen.
        server.get('/auth', function (req, res) {
            var token = "foo-token";
            res.cookie('authstate', token);
            var authorizationUrl = createAuthorizationUrl(token);
            res.redirect(authorizationUrl);
        });
Der Cookie kann genutzt werden, um zum Beispiel einen Login-Versuch einer bestimmten Anfrage im Code zuzuordnen. Nach erfolgreicher Authentifizierung des Users über den Microsoft-Login wird aus dem Login-Window heraus die Redirect-URL aufgerufen, welche wir bei der App-Registrierung angegeben haben. Dabei wird ein Access-Token an die Redirect-URL übermittelt. Mit Hilfe der Funktion acquireTokenWithAuthorizationCode aus der ADAL Library können wir dieses Access-Token ermitteln und abspeichern:
        server.get('/getAToken', function (req, res) {
            if (req.cookies.authstate !== req.query.state) {
                res.send('error: state does not match');
            }
            authenticationContext.acquireTokenWithAuthorizationCode(
                req.query.code,
                redirectUri,
                resource,
                clientId,
                clientSecret,
                function (err, response) {
                    var message = '';
                    if (err) {
                        message = 'error: ' + err.message + '\n';
                        res.status(400).send(message);
                    } else {
                        tokenResponse = response;
                        res.status(200).send("Logged in");
                    }            
                }
            );
        });
Das Access Token wird in der Variablen tokenResponse gespeichert.
Wenn man nun einen REST API Call aus Electron heraus absetzen will, schickt man für die Authentifizierung einfach das Access-Token im Authorization-Header des Calls mit:
        ajax({
            url: "https:/foo.sharepoint.com/_api/web/lists",
            "method": "GET",
            "contentType": "application/json;odata=verbose",
            "headers": {
                "Accept": "application/json;odata=verbose",
                "Authorization": "Bearer " + tokenResponse.accessToken,
                'Access-Control-Allow-Origin': '*'
            },
            "crossDomain": true,
            "async": true,
            "cache": false,
            "processData": false
        }).success(function (data) {
            console.log(JSON.stringify(data));
            event.returnValue = JSON.stringify(data);
        }).error(function (data) {
            console.log(JSON.stringify(data));
            event.returnValue = JSON.stringify(data);
        });
Den kompletten Scourcecode finden Sie hier.


Diesen Blogeintrag bewerten:


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

Nehmen Sie mit uns Kontakt auf!

Wir unterstützen Sie gerne bei Ihren 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