Autentisera och skydda webbtillägg

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

Den här artikeln beskriver endast autentisering för webbtillägg . Det gäller inte för pipelineaktivitetstillägg eller tjänstslutpunktstillägg.

Tips

För den senaste utvecklingsvägledningen för tillägg, inklusive teman och migrering från VSS. SDK, se utvecklarportalen för Azure DevOps Extension SDK.

Anropa REST-API:er från ditt tillägg

De flesta tillägg anropar Azure DevOps REST API:er för den aktuella användarens räkning.

  • Använda SDK REST-klienter: Autentisering hanteras automatiskt. Klienterna begär en åtkomsttoken från SDK och ställer in Authorization headern.

  • Använda anpassade HTTP-begäranden: Hämta en token från SDK och ange headern själv:

    import * as SDK from "azure-devops-extension-sdk";
    
    SDK.init();
    
    SDK.ready().then(async () => {
        const token = await SDK.getAccessToken();
        const authHeader = `Bearer ${token}`;
    
        // Use authHeader in your fetch/XMLHttpRequest calls
    });
    

Autentisera begäranden till din tjänst

När tillägget anropar en serverdelstjänst som du styr måste du kontrollera att begäran kom från ditt tillägg som körs i Azure DevOps. SDK:et tillhandahåller getAppToken(), som returnerar en JWT som är signerad med din förlängnings certifikat. Tjänsten validerar den här token för att autentisera begäran.

Hämta tilläggets nyckel

Tilläggets unika nyckel genereras när du publicerar. Använd den för att verifiera tokens äkthet från ditt tillägg.

  1. Gå till tilläggshanteringsportalen.
  2. Högerklicka på det publicerade tillägget och välj Certifikat.

key

Varning

Omfångsändringar gör att certifikatet ändras. Hämta en ny nyckel efter att du har ändrat behörigheter.

Generera en token för din tjänst

Använd getAppToken() för att få en JWT signerad med tilläggets certifikat och skicka det sedan till din tjänst:

import * as SDK from "azure-devops-extension-sdk";

SDK.init();

SDK.ready().then(async () => {
    const token = await SDK.getAppToken();
    
    // Pass this token to your backend as a header or query parameter
    const response = await fetch("https://your-service.example.com/api/data", {
        headers: {
            "Authorization": `Bearer ${token}`
        }
    });
});

Verifiera token

Serverdelstjänsten verifierar JWT med hjälp av tilläggets hemliga nyckel. I följande exempel visas hur du implementerar validering.

Viktigt!

Hårdkoda aldrig tilläggshemligheten i källkoden. Läs in den från miljövariabler, Azure Key Vault eller ett annat säkert konfigurationsarkiv.

.NET (konsolprogram)

Installera NuGet-paketet:

dotnet add package System.IdentityModel.Tokens.Jwt

Anmärkning

Använd version 7.x eller senare. Version 6.x och tidigare är inaktuella. Mer information finns i livscykeln för IdentityModel-versionen .

using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;

string secret = Environment.GetEnvironmentVariable("EXTENSION_SECRET")
    ?? throw new InvalidOperationException("EXTENSION_SECRET not configured");
string issuedToken = ""; // Token from the extension request

var validationParameters = new TokenValidationParameters()
{
    IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(secret)),
    ValidateIssuer = false,
    ValidateAudience = false,
    ValidateActor = false,
    RequireSignedTokens = true,
    RequireExpirationTime = true,
    ValidateLifetime = true
};

var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(issuedToken, validationParameters, out SecurityToken token);

ASP.NET Core Web API

Installera NuGet-paketet:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

Program.cs

using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

string secret = builder.Configuration["ExtensionSecret"]
    ?? throw new InvalidOperationException("ExtensionSecret not configured");

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateActor = false,
            RequireSignedTokens = true,
            RequireExpirationTime = true,
            ValidateLifetime = true
        };
    });

var app = builder.Build();

app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();

app.Run();

API-styrenhet:

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

[Route("api/[controller]")]
[Authorize]
public class SampleLogicController : ControllerBase
{
   // Requests without a valid token return 401 Unauthorized
}