Поделиться через


Аутентификация и защита веб-расширений

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Эта статья касается только аутентификации и безопасности для веб-расширенийи не затрагивает расширения задач Pipelines или расширения конечных точек служб. Для этих задач можно использовать публикацию вслужебной шины Azure.

Вызов REST API из расширения

Большинство расширений должны вызывать REST API Azure DevOps от имени текущего пользователя.

  • Если вы используете предоставленный JavaScript REST clients, проверка подлинности выполняется автоматически. Эти клиенты запрашивают маркер доступа из основного пакета SDK и задают его в заголовке авторизации запроса.

  • Если вы не используете предоставленные клиенты, необходимо запросить токен из Core SDK и установить его в заголовке авторизации вашего запроса.

    import * as SDK from "azure-devops-extension-sdk";
    import { getAccessToken } from "azure-devops-extension-sdk";
    
    SDK.init();
    
    getAccessToken().then((token) => {
        // Format the auth header
        const authHeader = `Bearer ${token}`;
    
        // Add token as an Authorization header to your request
        console.log(authHeader);
    });
    

Подсказка

Ознакомьтесь с нашей новой документацией по разработке расширений с помощью пакета SDK для расширений Azure DevOps.

Аутентифицируйте запросы к вашему сервису

Распространенный сценарий заключается в вызове бэкенд-сервиса из расширения. Чтобы убедиться, что эти вызовы поступают из вашего расширения, работающего в Azure DevOps, и для аутентификации текущего пользователя, а также для других сведений о контексте, вашему расширению предоставляется специальный тип токена. Этот токен содержит сведения о вызывающем устройстве и подписи, которую можно проверить, чтобы убедиться, что запрос исходит из вашего расширения.

Получение ключа расширения

Уникальный ключ расширения, созданный при публикации расширения, можно использовать для проверки подлинности запросов, сделанных из расширения.

Чтобы получить этот ключ, перейдите на портал управления расширениями , щелкните правой кнопкой мыши на опубликованное расширение , а затем выберите Сертификат .

key

Предупреждение

Изменения области в расширении вызывают изменение сертификата. Если вы вносите изменения в область, вам потребуется новый ключ расширения.

Сгенерируйте токен для предоставления службе

  1. Метод пакета SDK Core getAppToken возвращает обещание, которое при разрешении содержит маркер, подписанный сертификатом расширения.

    import * as SDK from "azure-devops-extension-sdk";
    import { getAppToken } from "azure-devops-extension-sdk";
    
    SDK.init();
    
    getAppToken().then((token) => {
    // Add token to your request
    console.log(token);
    });
    
  2. Передайте этот маркер в службу в качестве параметра запроса или заголовка запроса.

Анализ и проверка маркера

Здесь приведен пример разбора токена. Сначала скачайте и сохраните секрет для расширения на странице вашего издателя. Этот секрет должен быть доступен вашему приложению.

Платформа .NET Framework

Выполните следующую задачу, чтобы добавить одну ссылку, чтобы получить пример для компиляции.

Откройте диспетчер пакетов NuGet и добавьте ссылку на System.IdentityModel.Tokens.Jwt. Этот пример был создан с версией 6.8.0 этого пакета.

using System;
using System.IdentityModel.Tokens.Jwt;
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.Encoding.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);
            
            // Use the principal object as needed
            Console.WriteLine(principal.Identity.Name);
        }
    }
}

.NET Core — WebAPI

Выполните следующую задачу, чтобы добавить одну ссылку, чтобы получить этот пример для компиляции.

Откройте диспетчер пакетов 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.Extensions.DependencyInjection;
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.AddControllers();

            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, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseRouting();
            app.UseStaticFiles();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Ваши контроллеры API:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

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