Partage via


Authentification et sécurité

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

Cet article concerne uniquement les extensions web, et non les extensions de tâche pipelines ou les extensions de point de terminaison de service. Pour ces tâches, vous pouvez utiliser la tâche Publier sur Azure Service Bus.

Conseil

Consultez notre documentation la plus récente sur le développement d’extensions à l’aide du Kit de développement logiciel (SDK) d’extension Azure DevOps.

Appel d’API REST à partir de votre extension

La plupart des extensions ont besoin d’appeler des API REST Azure DevOps pour le compte de l’utilisateur actuel.

  • Si vous utilisez l’option fournie JavaScript REST clients, l’authentification est gérée automatiquement pour vous. Ces clients demandent automatiquement un jeton d’accès à partir du Kit de développement logiciel (SDK) principal et le définissent dans l’en-tête d’autorisation de la demande.

  • Si vous n’utilisez pas les clients fournis, vous devez demander un jeton à partir de celui-ci Core SDK et le définir dans l’en-tête d’autorisation de votre demande :

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

Authentification des demandes auprès de votre service

Un scénario courant consiste à effectuer des appels à un service back-end à partir d’une extension. Pour vérifier que ces appels proviennent de votre extension s’exécutant dans Azure DevOps et pour vérifier l’authenticité de l’utilisateur actuel (et d’autres informations de contexte), un type spécial de jeton est mis à la disposition de votre extension. Ce jeton contient des informations sur les personnes qui effectuent l’appel et une signature que vous pouvez valider pour savoir que la demande provient de votre extension.

Obtenir la clé de votre extension

La clé unique de votre extension (générée lors de la publication de l’extension) peut être utilisée pour vérifier l’authenticité des demandes effectuées à partir de votre extension.

Pour obtenir cette clé, cliquez avec le bouton droit sur une extension publiée, puis sélectionnez Certificat.

key

Avertissement

Les modifications d’étendue dans une extension entraînent la modification du certificat. Si vous apportez des modifications à l’étendue, vous avez besoin d’une nouvelle clé d’extension.

Générer un jeton pour fournir à votre service

  1. La méthode du Kit de développement logiciel (SDK) getAppToken Core retourne une promesse qui, lorsqu’elle est résolue, contient un jeton signé avec le certificat de votre extension.

    VSS.getAppToken().then(function(token){
        // Add token to your request
    });
    
  2. Transmettez ce jeton à votre service en tant que paramètre de requête ou en-tête de requête.

Analyser et valider le jeton

Voici un exemple d’analyse du jeton. Commencez par télécharger et stocker le secret de votre extension. Vous pouvez l’obtenir à partir de votre page d’éditeur. Ce secret doit être disponible pour votre application.

.NET Framework

Vous devez ajouter 1 référence pour obtenir cet exemple à compiler.

  1. Ouvrez le Gestionnaire de package NuGet et ajoutez une référence à System.IdentityModel.Tokens.Jwt. Cet exemple a été généré avec la version 5.2.2 de ce package.
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

Vous devez ajouter 1 référence pour obtenir cet exemple à compiler.

  1. Ouvrez le Gestionnaire de package NuGet et ajoutez une référence à System.IdentityModel.Tokens.Jwt. Cet exemple a été généré avec la version 5.1.4 de ce package.

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

Vos contrôleurs d’API :

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