Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022
この記事では、 Web 拡張機能 のみの認証について説明します。 パイプライン タスク拡張機能またはサービス エンドポイント拡張機能には適用されません。
ヒント
テーマ設定や VSS からの移行など、最新の拡張機能開発ガイダンスについて説明します。SDK については、 Azure DevOps Extension SDK 開発者ポータルを参照してください。
拡張機能から REST API を呼び出す
ほとんどの拡張機能では、現在のユーザーの代わりに Azure DevOps REST API が呼び出されます。
SDK REST クライアントの使用: 認証は自動的に処理されます。 クライアントは SDK にアクセス トークンを要求し、
Authorizationヘッダーを設定します。カスタム HTTP 要求の使用: SDK からトークンを要求し、ヘッダーを自分で設定します。
import * as SDK from "azure-devops-extension-sdk"; SDK.init(); SDK.ready().then(async () => { const token = await SDK.getAccessToken(); const authHeader = `Bearer ${token}`; // Use authHeader in your fetch/XMLHttpRequest calls });
サービスに対する要求を認証する
拡張機能が制御するバックエンド サービスを呼び出すときは、Azure DevOps で実行されている拡張機能から要求が送信されたことを確認する必要があります。 SDK には getAppToken()が用意されており、拡張機能の証明書で署名された JWT が返されます。 サービスは、このトークンを検証して要求を認証します。
拡張機能のキーを取得する
拡張機能の一意のキーは、発行時に生成されます。 これを使用して、拡張機能からのトークンの信頼性を確認します。
- 拡張機能管理ポータルに移動します。
- 発行した拡張機能を右クリックし、[証明書] を選択します。
Warnung
スコープを変更すると、証明書が変更されます。 スコープを変更した後に新しいキーを取得します。
サービスのトークンを生成する
getAppToken()を使用して、拡張機能の証明書で署名された JWT を取得し、サービスに渡します。
import * as SDK from "azure-devops-extension-sdk";
SDK.init();
SDK.ready().then(async () => {
const token = await SDK.getAppToken();
// Pass this token to your backend as a header or query parameter
const response = await fetch("https://your-service.example.com/api/data", {
headers: {
"Authorization": `Bearer ${token}`
}
});
});
トークンを検証する
バックエンド サービスは、拡張機能の秘密鍵を使用して JWT を検証します。 次の例は、検証を実装する方法を示しています。
Important
ソース コードで拡張機能シークレットをハードコーディングしないでください。 環境変数、Azure Key Vault、または別のセキュリティで保護された構成ストアから読み込みます。
.NET (コンソール アプリケーション)
NuGet パッケージをインストールします。
dotnet add package System.IdentityModel.Tokens.Jwt
注
バージョン 7.x 以降を使用します。 バージョン 6.x 以前は非推奨です。 詳細については、 IdentityModel バージョンのライフサイクル を参照してください。
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
string secret = Environment.GetEnvironmentVariable("EXTENSION_SECRET")
?? throw new InvalidOperationException("EXTENSION_SECRET not configured");
string issuedToken = ""; // Token from the extension request
var validationParameters = new TokenValidationParameters()
{
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(secret)),
ValidateIssuer = false,
ValidateAudience = false,
ValidateActor = false,
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true
};
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(issuedToken, validationParameters, out SecurityToken token);
ASP.NET Core Web API
NuGet パッケージをインストールします。
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Program.cs
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
string secret = builder.Configuration["ExtensionSecret"]
?? throw new InvalidOperationException("ExtensionSecret not configured");
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
ValidateIssuer = false,
ValidateAudience = false,
ValidateActor = false,
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true
};
});
var app = builder.Build();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
API コントローラー:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[Authorize]
public class SampleLogicController : ControllerBase
{
// Requests without a valid token return 401 Unauthorized
}