Hinzufügen der Benutzerauthentifizierung zu Go-Apps für Microsoft Graph

In diesem Artikel fügen Sie der Anwendung, die Sie unter Erstellen von Go-Apps mit Microsoft Graph erstellt haben, die Benutzerauthentifizierung hinzu. Anschließend verwenden Sie die Microsoft Graph-Benutzer-API, um den authentifizierten Benutzer abzurufen.

Hinzufügen der Benutzerauthentifizierung

Das Azure Identity Client Module for Go bietet viele TokenCredential Klassen, die OAuth2-Tokenflows implementieren. Das Microsoft Graph SDK für Go verwendet diese Klassen, um Aufrufe von Microsoft Graph zu authentifizieren.

Konfigurieren des Graph-Clients für die Benutzerauthentifizierung

Verwenden Sie zunächst die DeviceCodeCredential -Klasse, um mithilfe des Gerätecodeflows ein Zugriffstoken anzufordern.

  1. Fügen Sie . /graphhelper/graphhelper.go die folgende Funktion hinzu.

    func (g *GraphHelper) InitializeGraphForUserAuth() error {
        clientId := os.Getenv("CLIENT_ID")
        tenantId := os.Getenv("TENANT_ID")
        scopes := os.Getenv("GRAPH_USER_SCOPES")
        g.graphUserScopes = strings.Split(scopes, ",")
    
        // Create the device code credential
        credential, err := azidentity.NewDeviceCodeCredential(&azidentity.DeviceCodeCredentialOptions{
            ClientID: clientId,
            TenantID: tenantId,
            UserPrompt: func(ctx context.Context, message azidentity.DeviceCodeMessage) error {
                fmt.Println(message.Message)
                return nil
            },
        })
        if err != nil {
            return err
        }
    
        g.deviceCodeCredential = credential
    
        // Create an auth provider using the credential
        authProvider, err := auth.NewAzureIdentityAuthenticationProviderWithScopes(credential, g.graphUserScopes)
        if err != nil {
            return err
        }
    
        // Create a request adapter using the auth provider
        adapter, err := msgraphsdk.NewGraphRequestAdapter(authProvider)
        if err != nil {
            return err
        }
    
        // Create a Graph client using request adapter
        client := msgraphsdk.NewGraphServiceClient(adapter)
        g.userClient = client
    
        return nil
    }
    

    Tipp

    Wenn Sie verwenden goimports, werden möglicherweise einige Module aus Ihrer import Anweisung in graphhelper.go beim Speichern entfernt. Möglicherweise müssen Sie die Module zum Erstellen erneut hinzufügen.

  2. Ersetzen Sie die leere initializeGraph Funktion in graphtutorial.go durch Folgendes.

    func initializeGraph(graphHelper *graphhelper.GraphHelper) {
        err := graphHelper.InitializeGraphForUserAuth()
        if err != nil {
            log.Panicf("Error initializing Graph for user auth: %v\n", err)
        }
    }
    

Dieser Code initialisiert zwei Eigenschaften, ein DeviceCodeCredential -Objekt und ein GraphServiceClient -Objekt. Die InitializeGraphForUserAuth Funktion erstellt eine neue instance von DeviceCodeCredentialund verwendet dann diesen instance, um eine neue instance von GraphServiceClientzu erstellen. Jedes Mal, wenn ein API-Aufruf an Microsoft Graph über userClienterfolgt, werden die bereitgestellten Anmeldeinformationen verwendet, um ein Zugriffstoken abzurufen.

Testen von DeviceCodeCredential

Fügen Sie als Nächstes Code hinzu, um ein Zugriffstoken DeviceCodeCredentialvon abzurufen.

  1. Fügen Sie . /graphhelper/graphhelper.go die folgende Funktion hinzu.

    func (g *GraphHelper) GetUserToken() (*string, error) {
        token, err := g.deviceCodeCredential.GetToken(context.Background(), policy.TokenRequestOptions{
            Scopes: g.graphUserScopes,
        })
        if err != nil {
            return nil, err
        }
    
        return &token.Token, nil
    }
    
  2. Ersetzen Sie die leere displayAccessToken Funktion in graphtutorial.go durch Folgendes.

    func displayAccessToken(graphHelper *graphhelper.GraphHelper) {
        token, err := graphHelper.GetUserToken()
        if err != nil {
            log.Panicf("Error getting user token: %v\n", err)
        }
    
        fmt.Printf("User token: %s", *token)
        fmt.Println()
    }
    
  3. Erstellen Sie die App, und führen Sie sie aus, indem Sie ausführen go run graphtutorial. Geben Sie ein 1 , wenn Sie zur Eingabe einer Option aufgefordert werden. Die Anwendung zeigt eine URL und den Gerätecode an.

    Go Graph Tutorial
    
    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    1
    To sign in, use a web browser to open the page https://microsoft.com/devicelogin and
    enter the code RB2RUD56D to authenticate.
    
  4. Öffnen Sie einen Browser, und navigieren Sie zu der angezeigten URL. Geben Sie den angegebenen Code ein, und melden Sie sich an.

    Wichtig

    Achten Sie auf vorhandene Microsoft 365-Konten, die bei Ihrem Browser angemeldet sind, wenn Sie zu https://microsoft.com/deviceloginnavigieren. Verwenden Sie Browserfeatures wie Profile, Gastmodus oder privaten Modus, um sicherzustellen, dass Sie sich als das Konto authentifizieren, das Sie zu Testzwecken verwenden möchten.

  5. Kehren Sie nach Abschluss des Vorgangs zur Anwendung zurück, um das Zugriffstoken anzuzeigen.

    Tipp

    Nur zu Validierungs- und Debugzwecken können Sie Benutzerzugriffstoken (nur für Geschäfts-, Schul- oder Unikonten) decodieren, indem Sie den Onlinetokenparser von Microsoft unter verwendenhttps://jwt.ms. Die Analyse Ihres Tokens kann nützlich sein, wenn beim Aufrufen von Microsoft Graph Tokenfehler auftreten. Beispielsweise wird überprüft, ob der scp Anspruch im Token die erwarteten Microsoft Graph-Berechtigungsbereiche enthält.

Benutzer abrufen

Nachdem die Authentifizierung konfiguriert wurde, können Sie Ihren ersten Microsoft Graph-API-Aufruf durchführen. Fügen Sie Code hinzu, um den Namen und die E-Mail-Adresse des authentifizierten Benutzers abzurufen.

  1. Fügen Sie . /graphhelper/graphhelper.go die folgende Funktion hinzu.

    func (g *GraphHelper) GetUser() (models.Userable, error) {
        query := users.UserItemRequestBuilderGetQueryParameters{
            // Only request specific properties
            Select: []string{"displayName", "mail", "userPrincipalName"},
        }
    
        return g.userClient.Me().Get(context.Background(),
            &users.UserItemRequestBuilderGetRequestConfiguration{
                QueryParameters: &query,
            })
    }
    
  2. Ersetzen Sie die leere greetUser Funktion in graphtutorial.go durch Folgendes.

    func greetUser(graphHelper *graphhelper.GraphHelper) {
        user, err := graphHelper.GetUser()
        if err != nil {
            log.Panicf("Error getting user: %v\n", err)
        }
    
        fmt.Printf("Hello, %s!\n", *user.GetDisplayName())
    
        // For Work/school accounts, email is in Mail property
        // Personal accounts, email is in UserPrincipalName
        email := user.GetMail()
        if email == nil {
            email = user.GetUserPrincipalName()
        }
    
        fmt.Printf("Email: %s\n", *email)
        fmt.Println()
    }
    

Wenn Sie die App jetzt ausführen, begrüßt Sie die App nach der Anmeldung mit dem Namen.

Hello, Megan Bowen!
Email: MeganB@contoso.com

Code erläutert

Betrachten Sie den Code in der getUser Funktion. Es sind nur wenige Zeilen, aber es sind einige wichtige Details zu beachten.

Zugreifen auf "me"

Die Funktion verwendet den Anforderungs-Generator userClient.Me , der eine Anforderung an die Get-Benutzer-API erstellt. Auf diese API kann auf zwei Arten zugegriffen werden:

GET /me
GET /users/{user-id}

In diesem Fall ruft der Code den GET /me API-Endpunkt auf. Dieser Endpunkt ist eine Verknüpfungsmethode, um den authentifizierten Benutzer abzurufen, ohne seine Benutzer-ID zu kennen.

Hinweis

Da der GET /me API-Endpunkt den authentifizierten Benutzer abruft, ist er nur für Apps verfügbar, die die Benutzerauthentifizierung verwenden. Reine App-Authentifizierungs-Apps können nicht auf diesen Endpunkt zugreifen.

Anfordern bestimmter Eigenschaften

Die Funktion verwendet die Select -Eigenschaft in den Abfrageparametern der Anforderung, um die benötigten Eigenschaften anzugeben. Diese Eigenschaft fügt dem API-Aufruf den Abfrageparameter $select hinzu.

Stark typisierter Rückgabetyp

Die Funktion gibt ein Userable Objekt zurück, das aus der JSON-Antwort der API deserialisiert wurde. Da der Code verwendet Select, verfügen nur die angeforderten Eigenschaften über Werte im zurückgegebenen Userable Objekt. Alle anderen Eigenschaften verfügen über Standardwerte.

Nächster Schritt