Verwenden von Azure DevOps OAuth 2.0 zum Erstellen einer Web-App

Azure DevOps Services

Wichtig

Diese Informationen gelten nur für vorhandene Azure DevOps OAuth-Apps. Neue App-Entwickler sollten Microsoft Entra ID OAuth verwenden, um sie in Azure DevOps zu integrieren.

Azure DevOps ist ein Identitätsanbieter für OAuth 2.0-Apps. Mit unserer Implementierung von OAuth 2.0 können Entwickler ihre App für Benutzer autorisieren und Zugriffstoken für Azure DevOps-Ressourcen erhalten.

Erste Schritte mit Azure DevOps OAuth

1. Registrieren Ihrer App

  1. Wechseln Sie zum https://app.vsaex.visualstudio.com/app/register Registrieren Ihrer App.

  2. Wählen Sie die Bereiche aus, die Ihre Anwendung benötigt, und verwenden Sie dann dieselben Bereiche, wenn Sie Ihre App autorisieren. Wenn Sie Ihre App mithilfe der Vorschau-APIs registriert haben, registrieren Sie sie erneut, da die von Ihnen verwendeten Bereiche jetzt veraltet sind.

  3. Wählen Sie Anwendung erstellen aus.

    Die Seite mit den Anwendungseinstellungen wird angezeigt.

    Screenshot showing Applications settings for your app.

    • Wenn Azure DevOps Services die Autorisierungsgenehmigungsseite für Ihren Benutzer anzeigt, verwendet er Ihren Firmennamen, App-Namen und Beschreibungen. Außerdem werden die URLs für Ihre Unternehmenswebsite, App-Website und Dienst- und Datenschutzbestimmungen verwendet.

      Screenshot showing Visual Studio Codespaces authorization page with your company and app information.

    • Wenn Azure DevOps Services die Autorisierung eines Benutzers anfragt und der Benutzer ihn gewährt, wird der Browser des Benutzers mit dem Autorisierungscode zu Ihrer Autorisierungsrückruf-URL umgeleitet. Die Rückruf-URL muss eine sichere Verbindung (https) sein, um den Code zurück in die App zu übertragen und genau mit der url übereinzugleichen, die in Ihrer App registriert ist. Wenn dies nicht der Grund ist, wird eine 400-Fehlerseite anstelle einer Seite angezeigt, auf der der Benutzer aufgefordert wird, Ihrer App eine Autorisierung zu erteilen.

  4. Rufen Sie die Autorisierungs-URL auf, und übergeben Sie Ihre App-ID und autorisierte Bereiche, wenn Sie einen Benutzer autorisieren möchten, ihre App für den Zugriff auf ihre Organisation zu autorisieren. Rufen Sie die Zugriffstoken-URL auf, wenn Sie ein Zugriffstoken abrufen möchten, um eine REST-API für Azure DevOps Services aufzurufen.

Die Einstellungen für jede App, die Sie registrieren, stehen in Ihrem Profil https://app.vssps.visualstudio.com/profile/viewzur Verfügung.

2. Autorisieren Ihrer App

  1. Wenn Ihr Benutzer Ihre App nicht autorisiert hat, auf ihre Organisation zuzugreifen, rufen Sie die Autorisierungs-URL auf. Er ruft Sie mit einem Autorisierungscode zurück, wenn der Benutzer die Autorisierung genehmigt.
https://app.vssps.visualstudio.com/oauth2/authorize
        ?client_id={app ID}
        &response_type={Assertion}
        &state={state}
        &scope={scope}
        &redirect_uri={callback URL}
Parameter Typ Notizen
client_id GUID Die ID, die Ihrer App zugewiesen wurde, als sie registriert wurde.
response_type Zeichenfolge Assertion
state Zeichenfolge Kann ein beliebiger Wert sein. In der Regel ein generierter Zeichenfolgenwert, der den Rückruf mit der zugehörigen Autorisierungsanforderung korreliert.
scope Zeichenfolge Bereiche, die bei der App registriert sind. Durch Leerzeichen getrennt. Siehe verfügbare Bereiche.
redirect_uri URL Rückruf-URL für Ihre App. Muss genau mit der URL übereinstimmen, die bei der App registriert ist.
  1. Fügen Sie Ihrer Website einen Link oder eine Schaltfläche hinzu, der den Benutzer zum Azure DevOps Services-Autorisierungsendpunkt führt:
https://app.vssps.visualstudio.com/oauth2/authorize
        ?client_id=88e2dd5f-4e34-45c6-a75d-524eb2a0399e
        &response_type=Assertion
        &state=User1
        &scope=vso.work%20vso.code_write
        &redirect_uri=https://fabrikam.azurewebsites.net/myapp/oauth-callback

Azure DevOps Services fordert den Benutzer auf, Ihre App zu autorisieren.

Vorausgesetzt, der Benutzer akzeptiert, leitet Azure DevOps Services den Browser des Benutzers an Ihre Rückruf-URL um, einschließlich eines kurzlebigen Autorisierungscodes und des in der Autorisierungs-URL angegebenen Statuswerts:

https://fabrikam.azurewebsites.net/myapp/oauth-callback
        ?code={authorization code}
        &state=User1

3. Abrufen eines Zugriffs- und Aktualisierungstokens für den Benutzer

Verwenden Sie den Autorisierungscode, um ein Zugriffstoken (und Aktualisierungstoken) für den Benutzer anzufordern. Ihr Dienst muss eine DIENST-zu-Dienst-HTTP-Anforderung an Azure DevOps Services stellen.

URL – App autorisieren

POST https://app.vssps.visualstudio.com/oauth2/token

HTTP-Anforderungsheader – App autorisieren

Header Wert
Inhaltsart application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded

HTTP-Anforderungstext – App autorisieren

client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}

Ersetzen Sie die Platzhalterwerte im vorherigen Beispielanforderungstext:

  • {0}: URL-codierter geheimer Clientschlüssel, der beim Registrieren der App erworben wurde
  • {1}: URL-codierter "Code", der über den code Abfrageparameter zur Rückruf-URL bereitgestellt wird
  • {2}: Rückruf-URL, die bei der App registriert ist

C#-Beispiel zum Erstellen des Anforderungstexts – Autorisieren der App

public string GenerateRequestPostData(string appSecret, string authCode, string callbackUrl)
{
   return String.Format("client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}",
               HttpUtility.UrlEncode(appSecret),
               HttpUtility.UrlEncode(authCode),
               callbackUrl
        );
}

Antwort – Autorisieren der App

{
    "access_token": { access token for the user },
    "token_type": { type of token },
    "expires_in": { time in seconds that the token remains valid },
    "refresh_token": { refresh token to use to acquire a new access token }
}

Wichtig

Speichern Sie die refresh_token sicher, damit Ihre App den Benutzer nicht erneut zur Autorisierung auffordern muss. Zugriffstoken laufen schnell ab und sollten nicht beibehalten werden.

4. Verwenden des Zugriffstokens

Um ein Zugriffstoken zu verwenden, fügen Sie es als Bearertoken in den Autorisierungsheader Ihrer HTTP-Anforderung ein:

Authorization: Bearer {access_token}

Beispielsweise die HTTP-Anforderung zum Abrufen der letzten Builds für ein Projekt:

GET https://dev.azure.com/myaccount/myproject/_apis/build-release/builds?api-version=3.0
Authorization: Bearer {access_token}

5. Aktualisieren eines abgelaufenen Zugriffstokens

Wenn das Zugriffstoken eines Benutzers abläuft, können Sie das Aktualisierungstoken verwenden, das er im Autorisierungsfluss erworben hat, um ein neues Zugriffstoken abzurufen. Es ist wie der ursprüngliche Prozess für den Austausch des Autorisierungscodes für ein Zugriffs- und Aktualisierungstoken.

URL – Aktualisierungstoken

POST https://app.vssps.visualstudio.com/oauth2/token

HTTP-Anforderungsheader – Aktualisierungstoken

Header Wert
Inhaltsart application/x-www-form-urlencoded
Inhaltslänge Berechnete Zeichenfolgenlänge des Anforderungstexts (siehe das folgende Beispiel)
Content-Type: application/x-www-form-urlencoded
Content-Length: 1654

HTTP-Anforderungstext – Aktualisierungstoken

client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=refresh_token&assertion={1}&redirect_uri={2}

Ersetzen Sie die Platzhalterwerte im vorherigen Beispielanforderungstext:

  • {0}: URL-codierter geheimer Clientschlüssel, der beim Registrieren der App erworben wurde
  • {1}: URL-codiertes Aktualisierungstoken für den Benutzer
  • {2}: Rückruf-URL, die bei der App registriert ist

Antwort – Aktualisierungstoken

{
    "access_token": { access token for this user },
    "token_type": { type of token },
    "expires_in": { time in seconds that the token remains valid },
    "refresh_token": { new refresh token to use when the token has timed out }
}

Wichtig

Ein neues Aktualisierungstoken wird für den Benutzer ausgegeben. Speichern Sie dieses neue Token, und verwenden Sie es, wenn Sie das nächste Mal ein neues Zugriffstoken für den Benutzer abrufen müssen.

Beispiele

Sie finden ein C#-Beispiel, das OAuth implementiert, um Azure DevOps Services-REST-APIs in unserem C#-OAuth-GitHub-Beispiel aufzurufen.

Generieren des geheimen Clientschlüssels

Alle 5 Jahre läuft Ihr Anwendungsgeheimnis ab. Sie werden davon ausgegangen, dass Ihr App-Geheimnis neu generiert wird, um weiterhin Zugriffstoken und Aktualisierungstoken erstellen und verwenden zu können. Dazu können Sie auf die Schaltfläche "Geheimen Schlüssel generieren" klicken, die ein Dialogfeld öffnet, um zu bestätigen, dass Sie diese Aktion ausführen möchten.

Screenshot confirming secret regeneration.

Wenn Sie bestätigen, dass Sie neu generieren möchten, funktioniert der vorherige App-Schlüssel nicht mehr, und alle vorherigen Token, die mit diesem Geheimschlüssel versehen wurden, funktionieren ebenfalls nicht mehr. Achten Sie darauf, die Drehung dieses geheimen Clientschlüssels gut zu überprüfen, um alle Ausfallzeiten des Kunden zu minimieren.

Häufig gestellte Fragen (FAQs)

F: Kann ich OAuth mit meiner Mobiltelefon-App verwenden?

A: Nein. Azure DevOps Services unterstützt nur den Webserverfluss, daher gibt es keine Möglichkeit, OAuth zu implementieren, da Sie den geheimen App-Schlüssel nicht sicher speichern können.

F: Welche Fehler oder spezielle Bedingungen muss ich in meinem Code behandeln?

A: Stellen Sie sicher, dass Sie die folgenden Bedingungen behandeln:

  • Wenn Der Benutzer den Zugriff ihrer App verweigert, wird kein Autorisierungscode zurückgegeben. Verwenden Sie den Autorisierungscode nicht, ohne auf Denial zu überprüfen.
  • Wenn Der Benutzer die Autorisierung Ihrer App widerruft, ist das Zugriffstoken nicht mehr gültig. Wenn Ihre App das Token für den Zugriff auf Daten verwendet, wird ein Fehler von 401 zurückgegeben. Fordern Sie erneut die Autorisierung an.

F: Ich möchte meine Web-App lokal debuggen. Kann ich localhost für die Rückruf-URL verwenden, wenn ich meine App registriert?

A: Ja. Azure DevOps Services ermöglicht jetzt localhost in Ihrer Rückruf-URL. Stellen Sie sicher, dass Sie beim Registrieren Der App als Anfang der Rückruf-URL verwenden https://localhost .

F: Ich erhalte eine HTTP 400-Fehlermeldung, wenn ich versuche, ein Zugriffstoken abzurufen. Was ist möglicherweise falsch?

A: Überprüfen Sie, ob Sie den Inhaltstyp auf "application/x-www-form-urlencoded" in Ihrem Anforderungsheader festlegen.

F: Ich erhalte eine HTTP 401-Fehlermeldung, wenn ich ein OAuth-basiertes Zugriffstoken verwende, aber ein PAT mit demselben Bereich funktioniert einwandfrei. Warum?

A: Überprüfen Sie, ob der Zugriff auf Anwendungen von Drittanbietern über OAuth nicht vom Administrator Ihrer Organisation deaktiviert https://dev.azure.com/{your-org-name}/_settings/organizationPolicywurde. In diesem Szenario funktioniert der Fluss zum Autorisieren einer App und generieren ein Zugriffstoken, aber alle REST-APIs geben nur einen Fehler zurück, z. B. TF400813: The user "<GUID>" is not authorized to access this resource.

F: Kann ich OAuth mit den SOAP-Endpunkten und REST-APIs verwenden?

A: Nein. OAuth wird derzeit nur in den REST-APIs unterstützt.

F: Wie kann ich Details zu Anlagen für meine Arbeitsaufgabe mithilfe von Azure DevOps REST-APIs abrufen?

A: Rufen Sie zuerst die Arbeitsaufgabendetails mit Arbeitsaufgaben ab – Rest-API für Arbeitsaufgaben abrufen:

GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}

Um die Anlagendetails abzurufen, müssen Sie der URL den folgenden Parameter hinzufügen:

$expand=all

Mit den Ergebnissen erhalten Sie die Relations-Eigenschaft. Dort finden Sie die Anlagen-URL, und innerhalb der URL finden Sie die ID. Beispiel:

$url = https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/434?$expand=all&api-version=5.0

$workItem = Invoke-RestMethod -Uri $url -Method Get -ContentType application/json

$split = ($workitem.relations.url).Split('/')

$attachmentId = $split[$split.count - 1]

# Result: 1244nhsfs-ff3f-25gg-j64t-fahs23vfs