Autenticación y seguridad

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

Este artículo solo pertenece a las extensiones web y no a las extensiones de tareas de canalizaciones ni a las extensiones de punto de conexión de servicio. Para esas tareas, puede usar la tarea Publicar en Azure Service Bus.

Sugerencia

Consulte nuestra documentación más reciente sobre el desarrollo de extensiones mediante el SDK de extensión de Azure DevOps.

Llamada a las API REST desde la extensión

La mayoría de las extensiones tienen que llamar a las API rest de Azure DevOps en nombre del usuario actual.

  • Si usa el proporcionado JavaScript REST clients, la autenticación se controla automáticamente automáticamente. Estos clientes solicitan automáticamente un token de acceso desde el SDK principal y lo establecen en el encabezado autorización de la solicitud.

  • Si no usa los clientes proporcionados, debe solicitar un token de Core SDK y establecerlo en el encabezado Autorización de la solicitud:

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

Autenticación de solicitudes en el servicio

Un escenario común es realizar llamadas a un servicio back-end desde una extensión. Para comprobar que estas llamadas proceden de la extensión que se ejecuta en Azure DevOps y para comprobar la autenticidad del usuario actual (y otra información de contexto), se pone a disposición de la extensión un tipo especial de token. Este token contiene información sobre quién realiza la llamada y también una firma que puede validar para saber que la solicitud procede de la extensión.

Obtención de la clave de la extensión

La clave única de la extensión (que se genera cuando se publica la extensión) se puede usar para comprobar la autenticidad de las solicitudes realizadas desde la extensión.

Para obtener esta clave, haga clic con el botón derecho en una extensión publicada y seleccione Certificado.

key

Advertencia

Los cambios de ámbito en una extensión hacen que el certificado cambie. Si realiza cambios en el ámbito, necesita una nueva clave de extensión.

Generación de un token para proporcionar al servicio

  1. El método Core SDK getAppToken devuelve una promesa que, cuando se resuelve, contiene un token firmado con el certificado de la extensión.

    VSS.getAppToken().then(function(token){
        // Add token to your request
    });
    
  2. Pase este token al servicio como un parámetro de consulta o encabezado de solicitud.

Análisis y validación del token

Este es un ejemplo de análisis del token. Primero descargue y almacene el secreto de la extensión. Puede obtener esto desde la página del publicador. Este secreto debe estar disponible para la aplicación.

.NET Framework

Debe agregar 1 referencia para que este ejemplo se compile.

  1. Abra el Administrador de paquetes NuGet y agregue una referencia a System.IdentityModel.Tokens.Jwt. Este ejemplo se creó con la versión 5.2.2 de este paquete.
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

Debe agregar 1 referencia para que este ejemplo se compile.

  1. Abra el Administrador de paquetes NuGet y agregue una referencia a System.IdentityModel.Tokens.Jwt. Este ejemplo se creó con la versión 5.1.4 de este paquete.

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

Los controladores de API:

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