Compartilhar via


Autenticar e proteger extensões da Web

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

Este artigo se refere apenas à autenticação e à segurança para extensões da Web e não a extensões de tarefa pipelines ou extensões de ponto de extremidade de serviço. Para essas tarefas, você pode usar a Tarefa Publicar no Barramento de Serviço do Azure.

Chamar APIs REST de sua extensão

A maioria das extensões precisa chamar AS APIs REST do Azure DevOps em nome do usuário atual.

  • Se você estiver usando o fornecido JavaScript REST clients, a autenticação será tratada automaticamente para você. Esses clientes solicitam um token de acesso do SDK principal e o definem no cabeçalho de autorização da solicitação.

  • Se você não estiver usando os clientes fornecidos, precisará solicitar um token Core SDK e defini-lo no cabeçalho de Autorização da sua solicitação:

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

Dica

Confira nossa documentação mais recente sobre o desenvolvimento de extensão usando o SDK de Extensão do Azure DevOps.

Autenticar solicitações em seu serviço

Um cenário comum é fazer chamadas para um serviço de back-end de uma extensão. Para verificar se essas chamadas vêm de sua extensão em execução no Azure DevOps e para autenticar o usuário atual e outras informações de contexto, um tipo especial de token é fornecido para sua extensão. Esse token contém informações sobre o chamador e uma assinatura que você pode validar para garantir que a solicitação tenha origem na sua extensão.

Obter a chave da extensão

A chave exclusiva da extensão, gerada quando a extensão é publicada, pode ser usada para verificar a autenticidade das solicitações feitas de sua extensão.

Para obter essa chave, acesse o portal de gerenciamento de extensão, clique com o botão direito do mouse em uma extensão publicada e selecione Certificado.

chave

Aviso

Alterações de escopo em uma extensão fazem com que o certificado seja alterado. Se você fizer alterações no escopo, precisará de uma nova chave de extensão.

Gerar um token para fornecer ao seu serviço

  1. O método SDK getAppToken Principal retorna uma promessa que, quando resolvido, contém um token assinado com o certificado da sua extensão.

    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. Passe esse token para seu serviço como um parâmetro de consulta ou cabeçalho de solicitação.

Analisar e validar o token

Aqui está um exemplo de análise do token. Primeiro, baixe e armazene o segredo da sua extensão na página do publicador. Esse segredo deve estar disponível para seu aplicativo.

.NET Framework

Faça a tarefa a seguir para adicionar uma referência para obter o exemplo a ser compilado.

Abra o Gerenciador de Pacotes NuGet e adicione uma referência a System.IdentityModel.Tokens.Jwt. Este exemplo foi criado com a versão 6.8.0 deste pacote.

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

Faça a tarefa a seguir para adicionar uma referência para que este exemplo seja compilado.

Abra o Gerenciador de Pacotes NuGet e adicione uma referência a System.IdentityModel.Tokens.Jwt. Este exemplo foi criado com a versão 5.1.4 deste pacote.

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

Seus controladores de API:

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

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