Auth e segurança

Serviços de DevOps do Azure | Azure DevOps Server 2022 - Azure DevOps Server 2019

Este artigo refere-se apenas a 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.

Gorjeta

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

Chamando APIs REST da 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á automaticamente tratada para você. Esses clientes solicitam automaticamente um token de acesso do SDK principal e o definem no cabeçalho Authorization da solicitação.

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

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

Autenticar pedidos ao seu serviço

Um cenário comum é fazer chamadas para um serviço de back-end a partir de uma extensão. Para verificar se essas chamadas são provenientes da sua extensão em execução no Azure DevOps e para verificar a autenticidade do usuário atual (e outras informações de contexto), um tipo especial de token é disponibilizado para sua extensão. Este token contém informações sobre quem está fazendo a chamada e também uma assinatura que você pode validar para saber que a solicitação veio da sua extensão.

Obtenha a chave da sua extensão

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

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

key

Aviso

As 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.

Gere um token para fornecer ao seu serviço

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

    VSS.getAppToken().then(function(token){
        // Add token to your request
    });
    
  2. Passe esse token para o seu serviço como um parâmetro de consulta ou cabeçalho de solicitação.

Analise e valide o token

Aqui está um exemplo de análise do token. Primeiro baixe e armazene o segredo para sua extensão. Você pode obtê-lo na página do editor. Esse segredo precisa estar disponível para o seu aplicativo.

.NET Framework

Você deve adicionar 1 referência para obter este exemplo para compilar.

  1. 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.2.2 deste pacote.
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 - API Web

Você deve adicionar 1 referência para obter este exemplo para compilar.

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

Seus controladores de API:

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