Blog

Technische Informationen rund um das Thema Modernes Arbeiten

Kategorie: Uncategorized

Windows Virtual Desktop ist weltweit verfügbar

Am 30. September 2019 war es endlich soweit: Windows Virtual Desktop ist weltweit verfügbar. 

Dabei handelt es sich um ein virtualisiertes Windows mit Office, das über Azure bereitgestellt wird. Lizensiert wird der Virtual Desktop über Microsoft 365. Folgende Suiten beinhalten Windows 10 multi-session, Windows 10 oder Windows 7:

  • Microsoft 365 F1, E3, E5, A3, A5, Business
  • Windows 10 Enterprise E3, E5
  • Windows 10 Education A3, A5
  • Windows 10 VDA per user

Interessant auch die im Blogeintrag angedeutete Roadmap:

We also worked closely with our partner ecosystem to help our customers extend Windows Virtual Desktop and get the most out of existing virtualization investments.

  • Starting today, Citrix can extend Windows Virtual Desktop worldwide, including support for Windows 10 multi-session, Windows 7 with free Extended Security Updates for up to three years, and support for Windows Server 2008 R2 with free Extended Security Updates on Azure.
  • Later this year, VMware Horizon Cloud on Microsoft Azure will extend Windows Virtual Desktop and its benefits, such as Windows 10 Enterprise multi-session and support for Windows 7 with free Extended Security Updates for up to three years. Preview will be available by the end of the calendar year.
  • We also engaged with hardware partners, system integrators (SI), who provide turnkey desktop-as-a-service (DaaS) offerings, and value-added solution providers, who add capabilities such as printing, application layering, assessment, and monitoring on Azure Marketplace. Learn more about Windows Virtual Desktop partners on the documentation page.

General availability of Windows Virtual Desktop is just the beginning. We’ll continue to rapidly innovate and invest in desktop and app virtualization. We look forward to sharing more with you in the coming months. In the meantime, learn more on our product page and get started with Windows Virtual Desktop today.

Weiterführende Links: 

Benutzer mit Hilfe von Microsoft Graph finden

Wie in den Artikeln über MS Graph schon beschrieben, kann man damit auf vielfältigste Informationen aus der Microsoft Cloud zugreifen. 

Hierzu gibt es wichtige Voraussetzungen:

  • Die Applikation, die auf die Informationen zugreift, muss registriert sein. 
  • Die Applikation muss die richtigen Zugriffsberechtigungen haben.

Registrieren der Anwendung in Azure AD

Während man im Internet noch viele Einträge findet, dass die Applikation über das App-Registrierungsportal registrieren soll, hat sich für mich der Weg direkt aus https://portal.azure.com heraus als der bequemere Weg erwiesen. Für diejenigen, die es jedoch auch weiterhin über das App-Registrierungsportal vornehmen wollen oder müssen, hier noch einmal der Link:

Navigieren Sie zum Microsoft App-Registrierungsportal unter https://apps.dev.microsoft.com/.

Sie finden das neue Tool innerhalb des Azure-Portals unter Azure Active Directory -> App-Registrierungen (Vorschau).

Ein Klick auf Neue Registrierung startet den Neueintrag für eine neu zu registrierende Anwendung:

Tragen Sie den Namen der Applikation in das Feld Name ein. 

Unter Unterstützte Kontotypen wählen Sie, ob die Anwendung auch außerhalb des aktuellen Tenants zur Verfügung soll, andere Tenants darauf zugreifen dürfen, oder auch eine Anmeldung über ein Microsoft Konto möglich sein soll. 

Nur Konten in diesem Organisationsverzeichnis (Standardverzeichnis)
 
Alle Benutzer- und Gastkonten in Ihrem Verzeichnis können Ihre Anwendung oder API verwenden.
Verwenden Sie diese Option, wenn Ihre Zielgruppe sich innerhalb Ihrer Organisation befindet.
 
Konten in einem beliebigen Organisationsverzeichnis
 
Alle Benutzer und Gäste mit einem Geschäfts-, Schul- oder Unikonto von Microsoft können Ihre Anwendung oder API verwenden. Dazu gehören auch Bildungseinrichtungen und Unternehmen, die Office 365 verwenden.
Verwenden Sie diese Option, wenn Ihre Zielgruppe Kunden aus dem Unternehmens- oder Bildungsbereich sind.
 
Konten in allen Organisationsverzeichnissen und persönliche Microsoft-Konten (z. B. Skype, Xbox, Outlook.com)
 
Alle Benutzer mit einem Geschäfts-, Schul- oder Unikonto bzw. einem persönlichen Microsoft-Konto können Ihre Anwendung oder API verwenden. Dazu gehören Bildungseinrichten und Unternehmen, die Office 365 verwenden, wie auch persönliche Konten, die zur Anmeldung bei Diensten wie Xbox und Skype verwendet werden.
Mit dieser Option beziehen Sie die umfassendste Gruppe von Microsoft-Identitäten ein.
 
Aufgrund temporärer Unterschiede in der Funktionalität werden möglicherweise Fehler angezeigt, wenn Sie nach der Registrierung der Anwendung versuchen, zwischen unterstützten Zielgruppen zu wechseln.

Läuft die Anwendung als Webanwendung, wird als Umleitungs-URI gerne die URL der Webanwendung oder einer darunter liegenden Seiten angegeben – d.h. z. B. http://localhost:5050. Wie im Text angegeben, muss diese Angabe heute noch nicht zwingend hinterlegt werden – allerdings kommt es in vielen Fällen zu Fehlermeldungen, wenn hier kein Wert eingetragen ist. 

Nach Klick auf Registrieren werden alle Optionen für die Konfiguration der Anwendung verfügbar. 

Den erste wichtige Wert stellt die Anwendungs-ID dar. Diese werden Sie später für den Zugriff benötigen.

 

Die Konfiguration der Anwendungs- Registrierung

Drei weitere Einstellungen werden in den nächsten Schritten wichtig. 

  • Das Secret / “Geheime Clientschlüssel”
  • Authentifizierung
  • API-Berechtigungen

Das Secret – Geheime Clientschlüssel

Unter Zertifikate und “Geheimnisse” können Sie nun entweder ein Zertifikat hochladen oder ein sogenanntes Secret erstellen. Diese werden im späteren Verlauf für die Authentifizierung genutzt.

Das Bild unten zeigt die Erstellung eines Secrets (“Geheime Clientschlüssel”).

Nach dem Klick auf Hinzufügen wird das Secret erstellt. Beachten Sie auf dem folgenden Fenster den Hinweis in der Kopfzeile:

“Kopieren Sie den Wert des neuen geheimen Clientschlüssels. Er kann nach dem Verlassen dieser Seite nicht mehr abgerufen werden.”

Hier empfiehlt es sich die Informationen (Applikations ID und Secret) an einer zentralen Stelle abzulegen.

Authentifizierungseinstellungen

Die nächste Seite stellt die Authentifizierungsseite dar. Hier wählen Sie, welche Dienste für die Authentifizierungsmöglichkeiten für die Anwendung zur Verfügung stehen.  

Wenn Sie die Microsoft Authentication Library (MSAL) oder die Active Directory Authentication Library (ADAL) zum Erstellen von Anwendungen für Desktop- oder Mobilgeräte verwenden, können Sie einen der unten vorgeschlagenen Umleitungs-URIs auswählen oder oben einen benutzerdefinierten Umleitungs-URI eingeben. Weitere Informationen finden Sie in der Bibliotheksdokumentation.

Wichtig für die Anwendung ist auch die zweite Entscheidung: soll die Anwendung über ein Token zugreifen können, muss diese Option explizit aktiviert werden.

Ermöglicht einer Anwendung das Anfordern eines Tokens direkt vom Autorisierungsendpunkt. Dies empfiehlt sich nur, wenn die Anwendung eine Single-Page-Architektur (SPA) aufweist, keine Back-End-Komponenten umfasst oder eine Web-API über JavaScript aufruft.

API-Berechtigungen

Unter API-Berechtigungen geben Sie nun an, welche Berechtigungen die Anwendung beim Zugriff haben soll. Hier können Sie sehr filigran die Berechtigungen auf die unterschiedlichen Bereiche (Exchange, Azure AD, Kalender, Kontakte, Chat, …) einstellen.

Klicken Sie hierzu auf Berechtigung hinzufügen und wählen Sie den Bereich aus, für den Sie die Berechtigungen erteilen möchten.

Aktivieren Sie die entsprechenden Berechtigungen. Auf der rechten Seite neben den Berechtigungen sehen sie, ob nach der Aktivierung der Berechtigung eine “Einwilligung” durch einen Administrator notwendig ist. Sollte das notwendig sein, können Sie diese nach dem Speichern der Änderungen über den Punkt Administratorzustimmung für das Standardverzeichnis erteilen sofort zentral ausführen.

Sollte eine Zustimmung durch einen Adminstratoren (Consent) notwendig sein, können Sie diese nach dem Speichern der Änderungen über den Punkt Administratorzustimmung für das Standardverzeichnis erteilen sofort zentral ausführen.

Ein Beispiel (C#)

In diesem Beispiel soll aus Azure AD ein Benutzer herausgesucht werden. Diese Aufgabe übernimmt Graph_Find_User. Als Parameter wird der _userPrincipalName des zu suchenden Benutzers und das Token (die Erstellung des Tokens wird weiter unten beschrieben) für den Zugriff übergeben

Für die Ausführung der Suche nutze ich ein HttpRequestMessage. Diese bekommt als Parameter “Get” sowie die im Graph-Explorer ausgetestete URL https://graph.microsoft.com/v1.0/users/<User> mit.

Test der Abfrage im Graph Explorer

Dazu wird die String-Variable graphRequest aus dem Pfad zum Graph und den Parametern /User/ und <_userPrincipalName> zusammengesetzt.

In Zeile 14 wird über einen Header json als Format “vereinbart”.

In Zeile 15 wird der übergebene Token in die Abfrage als Header übernommen.

public ADAccount Graph_Find_User(string _userPrincipalName, string _token)
       {

            string _userID = string.Empty;
string _graphString = "https://graph.microsoft.com/v1.0/"; string _status = string.Empty; using (var _client = new HttpClient()) { string graphRequest = _graphString+ "users/"+_userPrincipalName; Uri _requestUri = new Uri(graphRequest); using (var _request = new HttpRequestMessage(HttpMethod.Get, graphRequest)) // endpoint + queryParameter = graphRequest { _request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token); ; Task<HttpResponseMessage> _response = _client.SendAsync(_request); _response.Wait(); var _responseTextTask = _response.Result.Content.ReadAsStringAsync(); _responseTextTask.Wait(); ADAccount _myAccount = new ADAccount(); _myAccount = JsonConvert.DeserializeObject<ADAccount>(_responseTextTask.Result); return _myAccount; } } }

Als Antwort lese ich die aus dem Graph-Explorer heraus schon zu erwartende JSON-Rückmeldung (Zeile 20/21), die ich (Zeile 23 / 24) in eine passende Klasse (ADAccount) einlese. Die Struktur der Klasse entspricht der aus dem Graph Explorer erwarteten Antwort:

Die Klasse ADAccount:

public class ADAccount
 {
     public IList<string> businessPhones { get; set; }
     public string displayName { get; set; }
     public string givenName { get; set;  }
     public string jobTitle { get; set; }
     public string mail { get; set; }
     public string mobilePhone { get; set; }
     public string officeLocation { get; set; }
     public string preferredLanguage { get; set; }
     public string surname{ get; set; }
     public string userPrincipalName { get; set; }
     public string id { get; set; }
    
 }

Authentifizierung (Token)

Um die Anwendung authentifizieren zu können (ich hatte bei der Registrierung der Anwendung die Option “Token” aktiviert), benötige ich ein Token

Dieses erstelle ich über _authContext.AcquireTokenAsync (Zeile 25).

Da meine Anwendung inzwischen einen etwas größeren Umfang angenommen hat, sind die meisten Konfigurationsparameter inzwischen in einer Azure SQL Datenbank gespeichert. Diese lese ich mir im ersten Teil in _cfgParams (Zeile 11) ein. In der Struktur liegen nach dem Einlesen Informationen wie die Benutzer-Domäne (Domain.onmicrosoft.com), die URL für Microsoft Graph, die APP ClientID (aus der Registrierung der Anwendung) sowie das App Secret (ebenfalls aus der Registrierung der Anwendung). 

Da die App ID und das Secret in der Datenbank verschlüsselt abgelegt sind, müssen beide entschlüsselt werden. Das erledigt bei mir eine zentrale Funktion _mwPE.DecryptWithByteArray (Zeile 21). Hier könnte z. B. die Version von diesem Link genutzt werden. Haben Sie die App ID und das Secret lokal in einem String, kann das natürlich entfallen.

Der eigentliche Aufruf von AcquireTokenAsync erfolgt eigentlich async (Zeile 24). Leider hat das in meiner Konstellation zu einem Problem geführt. Daher habe ich mich entschieden, den Aufruf etwas umzuformulieren und über Task<> den Ablauf zu steuern. Hat alles funktioniert, erhalten Sie hier das Token, das beim Aufruf von Graph_Find_User neben dem _userPrincipalName übergeben wird.

private async Task<string> AppAuthenticationAsync()
       {
           //  Constants

           mwHelper.PasswordEncoder _mwPE = new mwHelper.PasswordEncoder();

           try
           {
               GetFromWS _getFromWS = new GetFromWS();
               Config_Parameter _cfgParams = new Config_Parameter();
               _cfgParams = _getFromWS.Get_Cfg_Parameters();

               var _tenant = _cfgParams._userDomain;               //  "Domain.onmicrosoft.com";
               var _resource = _cfgParams._ADAppResource;          //  https://graph.microsoft.com/";
               var _clientID = _cfgParams._ADAppClientID;
               var _secret = _cfgParams._ADAppSecret;

               
               var _authority = _cfgParams._ADAppAuthority + _tenant;  // $"https://login.microsoftonline.com/{tenant}";
               var _authContext = new AuthenticationContext(_authority);
               var _credentials = new ClientCredential(_mwPE.DecryptWithByteArray(_clientID), _mwPE.DecryptWithByteArray(_secret));

               // var _authResult = await _authContext.AcquireTokenAsync(_resource, _credentials);
               Task<AuthenticationResult> _authResult = _authContext.AcquireTokenAsync(_resource, _credentials);
               _authResult.Wait();

               return _authResult.Result.AccessToken;
           }
           catch (Exception ex)
           {
               return ("Fehler bei der Erstellung des Accesstokens" + ex.Message);
           }

       }

Eigentlich war damit nicht viel Code notwendig, um einen Benutzer in Azure AD zu suchen.

Die Zeit, die ich damit verbracht hatte, die Puzzle-Steine zusammenzufügen war eher dem Lesen und Suchen geschuldet, da der Teufel wie immer im Detail liegt. 

Ich hatte in meinem Blog mal irgendwann geschrieben, dass ich kein Entwickler wäre – dazu stehe ich noch heute. Insofern soll das Beispiel nur eine Hilfestellung sein, wie ein Einstieg gelingen kann – es ist mit Sicherheit kein Code, der allen kritischen Sichten und Anforderungen genügt. 

Im übrigen  muss ich hier vielen Kollegen für die Code-Schnipsel danken. Viele Bausteine, die auch in mein Beispiel eingeflossen sind, fand ich unter https://vincentlauzon.com, stackoverflow.com (eine wirklich großartige und hilfreiche Seite), oder auch https://dasow.com.

Eine wichtige Voraussetzung für den Code ist die Einbindung unterschiedlicher NuGet-Pakete. Ich habe in meiner gesamten Lösung folgende Pakete eingebunden:

  • Microsoft.Graph
  • Microsoft.Graph.Core
  • Microsoft.Identity.Client
  • Microsoft.IdentityModel.Clients.ActiveDirectory
  • Newtonsoft.Json

Ich hoffe, das Beispiel hilft beim Einstieg…

Microsoft Graph – Erste APP

Hat man sich mit Microsoft Graph vertraut gemacht, kann man nun mit der ersten APP beginnen. Auch hierfür findet man auch hier auf der “Get started with Microsoft Graph”-Site  sehr gute Unterstützung.

Wählen Sie die Plattform, mit der Sie starten wollen. 

In Schritt 2 wird registrieren Sie die – für den Zugriff notwendige – App ID. Ich werde darauf in einem neuen Blogeintrag noch einmal detaillierter eingehen.

Die App ID benötigen Sie später bei der Erstellung der APP noch einmal. Am besten gleich kopieren und irgendwo für den späteren Zugriff speichern.

Als nächstes können Sie die Solution für Visual Studio 2017 herunterladen. 

Entpacken Sie die Solution (msgraph-training-uwp.zip). Im Verzeichnis der Solution finden Sie eine Readme.md. Diese erläutert die nächsten Schritte:

To run the completed project in this folder, you need the following:

  • [Visual Studio](https://visualstudio.microsoft.com/vs/) installed on your development machine. If you do not have Visual Studio, visit the previous link for download options. (**Note:** This tutorial was written with Visual Studio 2017 version 15.81. The steps in this guide may work with other versions, but that has not been tested.)

Der nächste Schritt – laut Readme.md – ist die Anpassung der durch die Tutorial-Site durchgeführte Registrierung: 

Register a native application with the Application Registration Portal

  • Open a browser and navigate to the [Application Registration Portal](https://apps.dev.microsoft.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**.
  • Select the APP.
  • On the **Register your application** page, set the **Application Name** to **UWP Graph Tutorial** and select **Create**.
  • On the **UWP Graph Tutorial Registration** page, under the **Properties** section, copy the **Application Id** as you will need it later.
  • Scroll down to the **Platforms** section.
  • Select **Add Platform**.
  • In the **Add Platform** dialog, select **Native Application**.
  • Scroll to the bottom of the page and select **Save**.

Nun kann die Solution geöffnet werden. Es fallen sofort die “Fehlermeldungen” ins Auge:

Wie in der Readme.md beschrieben, muss man kleinere Anpassungen machen, damit die Ausführung gelingt:

  • Open `graph-tutorial.sln` in Visual Studio.
  • Edit the `OAuth.resw` file in visual studio.Replace `YOUR_APP_ID_HERE` with the **Application Id** you got from the App Registration Portal.
  • In Solution Explorer, right-click the **graph-tutorial** solution and choose **Restore NuGet Packages**.

Danach können Sie das Projekt ausführen.

Bei der ersten Anmeldung kommt ein entscheidender Punkt. Wurde in Azure (z. B. durch den Administrator) noch kein “Consent” erteilt, wird für die APP nun nachgefragt, ob die Berechtigungen für die APP akzeptiert werden. Die Berechtigungen müssen spätestens jetzt durch einen Klick auf “Akzeptieren” erteilt werden.

Microsoft Graph – Der Graph Explorer

Möchte man sich mit Microsoft Graph aus Entwickler-Sicht nähern, dann ist – neben der API Reference und den Dokumenten – Microsoft Graph Explorer eine sehr gute Möglichkeit. Man findet ihn auf der Developer-Site für Microsoft Graph.

The Microsoft Graph explorer is a tool that lets you make requests and see responses against the Microsoft Graph.

Bereits ohne Anmeldung hat man hier die Möglichkeit, erste Erfahrungen zu sammeln.  Im ersten Schritt werden ein paar Beispiel-Anfragen am linken Rand angezeigt. Diese drehen sich um den eigenen Benutzer – ohne Anmeldung um einen Demo-Benutzer. Man findet dort vordefinierte Abfragen zum Profil, zum Profilbild, zu E-Mails oder  zu Elementen in OneDrive. Wählt man eine der Abfragen aus, wird in der Query-Zeile die entsprechende Anfrage angezeigt.

In der Response-Anzeige bekommt man die Antworten angezeigt. 

Möchte man eine Übersicht über die Bandbreite von Microsoft Graph bekommen, klickt man auf den kleinen Link unterhalb der Liste der vorgefertigten Abfragen “show more samples“. Nun kann man aus der Fülle der Funktionen wählen – alles, was das Herz begehrt… 

Auswahl der Beispielkategorien im Graph Explorer

Damit öffnet man sich z. B. auch Zugriff auf Abfragen rund um die angelegten Benutzer. 

Ein kurzer Blick in die API Reference hilft einem dabei, etwas mit den Queries spielen zu können… 

You can access users through Microsoft Graph in two ways:

  • By their ID, /users/{id | userPrincipalName}
  • By using the /me alias for the signed-in user, which is the same as /users/{signed-in user's id}"

So kann man direkt an “/users/” den Namen eines Accounts anfügen und bekommt als Antwort dann die entsprechenden Informationen zurück.

Je nach Modul tauchen nun auch nicht mehr nur die Methode “GET” in den Beispielen auf. Man findet nun auch Beispiele für “POST” und “PATCH” – d.h. z. B. für das Anlegen eines Benutzers oder Ändern von Benutzereigenschaften. Diese können aber erst getestet werden, wenn man sich mit einem Microsoft Account angemeldet hat. 

Back again

Es ist nun eine ganze Zeit her, dass ich mich mit einem Blog beschäftigt habe. Durch die “Scharfschaltung” der DSGVO im Mai letzten Jahres, hatte ich erst einmal davon abgesehen, weiterhin BLOG zu schreiben.

Aber es lag mit Sicherheit nicht nur daran. In den letzten Monaten habe ich mich sehr spezialisierten Themen beschäftigt. 

  • Ich habe die bei uns eingesetzte Callcenter-Lösung um Möglichkeiten erweitert – und viel über Web Services, SQL, C# etc. gelernt.
  • Es ist eine Schnittstelle zwischen Skype for Business und SAP C4C entstanden. Bei Anruf droht Skype nun mit der Seite aus C4C, die dem Kunden / Ansprechpartner zugeordnet ist.
  • Ein kleines Outlook PlugIn übersetzt nun mit Hilfe der Microsoft Cognitive Services Mails (ok, schon fast wieder überfällig, da es hier schon Lösungen gibt), ein weiteres PlugIn berechnet die Anfahrtszeiten zu Terminen.
  • Spannend war die Auseinandersetzung mit einem neuen Cloud Provider, der sich auf Business Prozesse spezialisiert hat. Alles das, was mir in SharePoint oder Flow immer gefehlt hat quasi out-of-the Box.
  • Am rühmlichen Ende stand die Beschäftigung mit Microsoft Graph. Letztendlich ging es um die Frage, wie ein Zugriff auf Azure Active Directory umgesetzt werden kann, der auch in naher Zukunft noch funktionieren wird. Dabei lernt man viel über Microsoft Azure.

Viele Themen, die ich nun in der Folge wieder aufarbeiten und das, was ich dabei gelernt habe, mitteilen möchte. Vielleicht hilft es ja jemandem… 

© 2019 Blog

Theme von Anders NorénHoch ↑