Autenticación y seguridad

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018 - TFS 2017

Nota

Esta página solo pertenece a las extensiones weby no Pipelines de tareas o 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 Azure DevOps Extension.

Llamada a las API REST desde la extensión

La mayoría de las extensiones tienen la necesidad de llamar a Azure DevOps API REST en nombre del usuario actual.

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

  • Si no usa los clientes proporcionados, debe solicitar un token de y establecerlo en el encabezado Core SDK 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 a su servicio

Un escenario común es realizar llamadas a un servicio back-end desde una extensión. Para comprobar que estas llamadas son procedentes 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 ofrece un tipo especial de token a la extensión. Este token contiene información sobre quién realiza la llamada y también una firma que puede validar para saber que la solicitud provenía de la extensión.

Obtener 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 devuelve una promesa que, cuando se getAppToken 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 un encabezado de solicitud.

Análisis y validación del token

Este es un ejemplo de análisis del token. En primer lugar, descargue y almacene el secreto de la extensión. Puede obtenerlo en la página del publicador. Este secreto debe estar disponible para la aplicación.

.NET Framework

Debe agregar una referencia para que este ejemplo se compile.

  1. Abra el NuGet Administrador de paquetes y agregue una referencia a System.IdentityModel.Tokens.Jwt. Este ejemplo se ha creado 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 una referencia para que este ejemplo se compile.

  1. Abra el NuGet Administrador de paquetes y agregue una referencia a System.IdentityModel.Tokens.Jwt. Este ejemplo se ha creado 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
{
   // ...
}