認証とセキュリティ

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

この記事は、Pipelines タスク拡張機能やサービス エンドポイント拡張機能ではなく、Web 拡張機能にのみ関連します。 これらのタスクでは、Azure Service Bus への発行タスクを使用できます。

ヒント

Azure DevOps 拡張機能 SDK を使用した拡張機能開発に関する最新のドキュメントを確認してください。

拡張機能から REST API を呼び出す

ほとんどの拡張機能では、現在のユーザーの代わりに Azure DevOps REST API を呼び出す必要があります。

  • 指定 JavaScript REST clientsされた認証を使用している場合は、自動的に認証が処理されます。 これらのクライアントは、コア SDK からアクセス トークンを自動的に要求し、要求の Authorization ヘッダーに設定します。

  • 指定されたクライアントを使用していない場合は、トークンを要求し、要求の Core SDK Authorization ヘッダーに設定する必要があります。

    VSS.require(["VSS/Authentication/Services"],
        function (VSS_Auth_Service) {
            VSS.getAccessToken().then(function(token){
                // Format the auth header
                var authHeader = VSS_Auth_Service.authTokenManager.getAuthorizationHeader(token);
    
                // Add token as an Authorization header to your request
            });
        });
    

サービスへの要求の認証

一般的なシナリオは、拡張機能からバックエンド サービスを呼び出す場合です。 これらの呼び出しが Azure DevOps で実行されている拡張機能から送信されていることを確認し、現在のユーザー (およびその他のコンテキスト情報) の信頼性を確認するために、特別な種類のトークンが拡張機能で使用できるようになります。 このトークンには、呼び出しを行っているユーザーに関する情報と、要求が拡張機能から送信されたことを確認できる署名も含まれます。

拡張機能のキーを取得する

拡張機能の一意キー (拡張機能の公開時に生成されます) を使用して、拡張機能から行われた要求の信頼性を確認できます。

このキーを取得するには、発行された拡張機能を右クリックし、[証明書] を選択します

キー

警告

拡張機能のスコープを変更すると、証明書が変更されます。 スコープを変更する場合は、新しい拡張キーが必要です。

サービスに提供するトークンを生成する

  1. Core SDK getAppToken メソッドは、解決されると、拡張機能の証明書で署名されたトークンが含まれているという約束を返します。

    VSS.getAppToken().then(function(token){
        // Add token to your request
    });
    
  2. このトークンをクエリ パラメーターまたは要求ヘッダーとしてサービスに渡します。

トークンを解析して検証する

トークンの解析のサンプルを次に示します。 まず、拡張機能のシークレットをダウンロードして保存します。 これは、発行元ページから取得できます。 このシークレットは、アプリケーションで使用できる必要があります。

.NET Framework

このサンプルをコンパイルするには、1 つの参照を追加する必要があります。

  1. NuGet パッケージ マネージャーを開き、System.IdentityModel.Tokens.Jwt への参照を追加します。 このサンプルは、このパッケージのバージョン 5.2.2 でビルドされました。
using System.Collections.Generic;
using System.ServiceModel.Security.Tokens;
using Microsoft.IdentityModel.Tokens;

namespace TokenSample
{
	class Program
	{
		static void Main(string[] args)
		{
			string secret = ""; // Load your extension's secret
			string issuedToken = ""; // Token you are validating
				
			var validationParameters = new TokenValidationParameters()
			{
				IssuerSigningKey = new SymmetricSecurityKey(System.Text.UTF8Encoding.UTF8.GetBytes(secret)),
				ValidateIssuer = false,
				RequireSignedTokens = true,
				RequireExpirationTime = true,
				ValidateLifetime = true,
				ValidateAudience = false,
				ValidateActor = false
			};

			SecurityToken token = null;
			var tokenHandler = new JwtSecurityTokenHandler();
			var principal = tokenHandler.ValidateToken(issuedToken, validationParameters, out token);
		}
	}
}

.NET Core - WebAPI

このサンプルをコンパイルするには、1 つの参照を追加する必要があります。

  1. NuGet パッケージ マネージャーを開き、System.IdentityModel.Tokens.Jwt への参照を追加します。 このサンプルは、このパッケージのバージョン 5.1.4 でビルドされました。

Startup.cs

using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace TokenSample.Core.API
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            string _secret = "ey9asfasdmax..<the secret key downloaded from the Azure DevOps Services publisher page>.9faf7eh";
	    
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer((o) =>
                    {
                        o.TokenValidationParameters = new TokenValidationParameters()
                        {
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secret)),
                            ValidateIssuer = false,
                            ValidateAudience = false,
                            ValidateActor = false,
                            RequireSignedTokens = true,
                            RequireExpirationTime = true,
                            ValidateLifetime = true
                        };    
                    });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseMvc();
            app.UseStaticFiles();
        }
    }
}

API コントローラー:

[Route("api/[controller]"), 
 Authorize()]
public class SampleLogicController : Controller
{
   // ...
}