次の方法で共有


Azure DevOps OAuth 2.0 を使用して Web アプリを作成する

Azure DevOps Services

重要

この情報は、既存の Azure DevOps OAuth アプリのみを対象としています。 新しいアプリ開発者は、 Microsoft Entra ID OAuth を使用して Azure DevOps と統合する必要があります。

Azure DevOps は、OAuth 2.0 アプリの ID プロバイダーです。 OAuth 2.0 の実装により、開発者はユーザーのアプリを承認し、Azure DevOps リソースのアクセス トークンを取得できます。

Azure DevOps OAuth の概要

1. アプリを登録する

  1. https://app.vsaex.visualstudio.com/app/registerに移動してアプリを登録します。

  2. アプリケーションに必要な スコープ を選択し、アプリの認証を するときに同じスコープを使用します。 プレビュー API を使用してアプリを登録した場合は、使用したスコープが非推奨になったため、再登録します。

  3. アプリケーションの作成を選択します。

    アプリケーション設定ページが表示されます。

    アプリのアプリケーション設定を示すスクリーンショット。

    • Azure DevOps Services は、承認承認ページをユーザーに提示するときに、会社名、アプリ名、説明を使用します。 また、会社の Web サイト、アプリ Web サイト、サービス利用規約とプライバシーに関する声明の URL も使用します。

      会社とアプリの情報を含む Visual Studio Codespaces 承認ページを示すスクリーンショット。

    • Azure DevOps Services がユーザーの承認を要求し、ユーザーがそれを許可すると、ユーザーのブラウザーは承認コードを含む承認コールバック URL にリダイレクトされます。 コールバック URL は、コードをアプリに転送し、アプリに登録されている URL と正確に一致するセキュリティで保護された接続 (https) である必要があります。 そうでない場合は、アプリに承認を付与するようにユーザーに求めるページではなく、400 エラー ページが表示されます。

  4. 組織にアクセスするアプリをユーザーに承認させる場合は、承認 URL を呼び出し、アプリ ID と承認されたスコープを渡します。 Azure DevOps Services REST API を呼び出すアクセス トークンを取得する場合は、アクセス トークン URL を呼び出します。

登録する各アプリの設定は、プロファイル https://app.vssps.visualstudio.com/profile/viewから入手できます。

2. アプリを承認する

  1. ユーザーが組織にアクセスするアプリを承認していない場合は、承認 URL を呼び出します。 ユーザーが承認を承認すると、承認コードを使用して呼び出されます。
https://app.vssps.visualstudio.com/oauth2/authorize
        ?client_id={app ID}
        &response_type={Assertion}
        &state={state}
        &scope={scope}
        &redirect_uri={callback URL}
パラメーター Notes
client_id GUID 登録時にアプリに割り当てられた ID。
response_type string Assertion
state string 任意の値が可能です。 通常、コールバックとそれに関連付けられている承認要求を関連付ける生成された文字列値。
scope string アプリに登録されているスコープ。 スペースを区切ります。 使用可能なスコープ 参照してください
redirect_uri URL アプリのコールバック URL。 アプリに登録されている URL と完全に一致する必要があります
  1. ユーザーを Azure DevOps Services 承認エンドポイントに移動するリンクまたはボタンをサイトに追加します。
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 は、アプリの承認をユーザーに求めます。

ユーザーが同意すると、Azure DevOps Services は、有効期間の短い承認コードと承認 URL に指定された状態値を含む、ユーザーのブラウザーをコールバック URL にリダイレクトします。

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

3. ユーザーのアクセス トークンと更新トークンを取得する

承認コードを使用して、ユーザーのアクセス トークン (および更新トークン) を要求します。 サービスは、Azure DevOps Services に対してサービス間 HTTP 要求を行う必要があります。

URL - アプリを承認する

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

HTTP 要求ヘッダー - アプリを承認する

ヘッダー Value
Content-Type application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded

HTTP 要求本文 - アプリを承認する

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}

前のサンプル要求本文のプレースホルダー値を置き換えます。

  • {0}: アプリの登録時に取得された URL でエンコードされたクライアント シークレット
  • {1}: code クエリ パラメーターを介してコールバック URL に提供される URL エンコードされた "コード"
  • {2}: アプリに登録されているコールバック URL

要求本文を形成する C# の例 - アプリを承認する

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
        );
}

応答 - アプリを承認する

{
    "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 }
}

重要

アプリがユーザーに再度承認を求める必要がないように、 refresh_token を安全に保持します。 アクセス トークンの有効期限がすぐに切れるので、保持しないでください。

4. アクセス トークンを使用する

アクセス トークンを使用するには、HTTP 要求の Authorization ヘッダーにベアラー トークンとして含めます。

Authorization: Bearer {access_token}

たとえば、プロジェクトの最近のビルドする HTTP 要求は次のとおりです。

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

5. 期限切れのアクセス トークンを更新する

ユーザーのアクセス トークンの有効期限が切れた場合は、承認フローで取得した更新トークンを使用して、新しいアクセス トークンを取得できます。 これは、アクセストークンと更新トークンの承認コードを交換するための元のプロセスのようなものです。

URL - 更新トークン

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

HTTP 要求ヘッダー - 更新トークン

ヘッダー Value
Content-type application/x-www-form-urlencoded
Content-length 要求本文の計算された文字列の長さ (次の例を参照)
Content-Type: application/x-www-form-urlencoded
Content-Length: 1654

HTTP 要求本文 - 更新トークン

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

前のサンプル要求本文のプレースホルダー値を置き換えます。

  • {0}: アプリの登録時に取得された URL でエンコードされたクライアント シークレット
  • {1}: ユーザーの URL エンコードされた更新トークン
  • {2}: アプリに登録されているコールバック URL

応答 - 更新トークン

{
    "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 }
}

重要

ユーザーに対して新しい更新トークンが発行されます。 この新しいトークンを保持し、次回ユーザーの新しいアクセス トークンを取得する必要がある場合に使用します。

サンプル

OAuth を実装して Azure DevOps Services REST API を呼び出す C# サンプルは、 C# OAuth GitHub サンプルにあります。

クライアント シークレットを再生成する

5 年ごとに、アプリケーション シークレットの有効期限が切れます。 引き続きアクセス トークンと更新トークンを作成して使用できるように、アプリ シークレットを再生成する必要があります。 これを行うには、[シークレットの再生成] ボタンをクリックすると、この操作を完了することを確認するダイアログがポップアップ表示されます。

シークレットの再生成を確認するスクリーンショット。

再生成することを確認すると、以前のアプリ シークレットは機能しなくなり、このシークレットで作成された以前のすべてのトークンも機能しなくなります。 顧客のダウンタイムを最小限に抑えるために、このクライアント シークレットのローテーションを十分に行ってください。

よく寄せられる質問 (FAQ)

Q: 携帯電話アプリで OAuth を使用できますか?

A: いいえ。 Azure DevOps Services は Web サーバー フローのみをサポートしているため、アプリ シークレットを安全に格納できないため、OAuth を実装する方法はありません。

Q: コードで処理する必要があるエラーや特別な条件は何ですか?

A: 次の条件を処理していることを確認します。

  • ユーザーがアプリのアクセスを拒否した場合、承認コードは返されません。 拒否を確認せずに承認コードを使用しないでください。
  • ユーザーがアプリの承認を取り消した場合、アクセス トークンは無効になります。 アプリがトークンを使用してデータにアクセスすると、401 エラーが返されます。 もう一度承認を要求します。

Q: Web アプリをローカルでデバッグする必要があります。 アプリを登録するときにコールバック URL に localhost を使用できますか?

回答: はい。 Azure DevOps Services では、コールバック URL で localhost が許可されるようになりました。 アプリを登録するときに、コールバック URL の先頭として https://localhost を使用していることを確認します。

Q: アクセス トークンを取得しようとすると、HTTP 400 エラーが発生します。 何が間違っている可能性がありますか?

A: 要求ヘッダーでコンテンツ タイプを application/x-www-form-urlencoded に設定していることを確認します。

Q: OAuth ベースのアクセス トークンを使用すると HTTP 401 エラーが発生しますが、スコープが同じ PAT でも問題ありません。 なぜですか?

A: 組織の管理者が、https://dev.azure.com/{your-org-name}/_settings/organizationPolicyで OAuth 経由で Third-party アプリケーション アクセスを無効にしていないことを確認します。 このシナリオでは、アプリを承認し、アクセス トークンを生成するフローが機能しますが、すべての REST API は、次のようなエラーのみを返します TF400813: The user "<GUID>" is not authorized to access this resource.

Q: SOAP エンドポイントと REST API で OAuth を使用できますか。

A: いいえ。 OAuth は REST API でのみサポートされます。

Q: Azure DevOps REST API を使用して作業項目の添付ファイルの詳細を取得するにはどうすればよいですか?

A: 次の手順を実行します。

  1. Work アイテムを使用して作業項目の詳細を取得する - 作業項目の取得 REST API:

    GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}
    
  2. 添付ファイルの詳細を取得するには、URL に次のパラメーターを追加します。

    $expand=all
    
  3. 結果を使用して、relations プロパティを取得します。 そこに添付ファイルの URL があり、URL 内で ID を見つけることができます。 次に例を示します。

    $url = https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/434?$expand=all&api-version=6.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