分享方式:


驗證和安全性

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

本文僅與 Web 延伸模組相關,而非管線工作延伸模組或服務端點延伸模組。 針對這些工作,您可以使用 [發佈至 Azure 服務匯流排 工作]。

提示

請參閱使用 Azure DevOps 擴充功能 SDK 進行擴充功能開發的最新檔。

從擴充功能呼叫 REST API

大部分的擴充功能都需要代表目前使用者呼叫 Azure DevOps REST API。

  • 如果您使用提供的 JavaScript REST clients,系統會自動為您處理驗證。 這些客戶端會自動向核心 SDK 要求存取令牌,並將它設定在要求的授權標頭中。

  • 如果您未使用提供的用戶端,您需要向 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
{
   // ...
}