Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
本文仅适用于 Web 扩展的身份验证和安全性,而不适用于 Pipelines 任务扩展或服务终结点扩展。 对于此类任务,您可以使用 Publish to Azure Service Bus 任务。
从扩展调用 REST API
大多数扩展都需要代表当前用户调用 Azure DevOps REST API。
如果您使用提供的
JavaScript REST clients,则会自动为您处理身份验证过程。 这些客户端从核心 SDK 请求访问令牌,并在请求的 Authorization 标头中设置它。如果不使用提供的客户端,则需要从
Core SDK请求令牌,并将其设置在请求的授权标头中。import * as SDK from "azure-devops-extension-sdk"; import { getAccessToken } from "azure-devops-extension-sdk"; SDK.init(); getAccessToken().then((token) => { // Format the auth header const authHeader = `Bearer ${token}`; // Add token as an Authorization header to your request console.log(authHeader); });
小窍门
查看有关使用 Azure DevOps 扩展 SDK 进行扩展开发的最新文档。
对您的服务请求进行身份验证
常见方案是从扩展调用后端服务。 若要验证这些调用是否来自 Azure DevOps 中运行的扩展,并验证当前用户和其他上下文信息,请向扩展提供特殊类型的令牌。 此令牌包含有关调用方的信息,并包含一个可以供您验证的签名,以确保请求是从您的扩展程序发出的。
获取扩展程序的密钥
扩展的唯一密钥(在发布扩展时生成)可用于验证从扩展发出的请求的真实性。
若要获取此密钥,请转到 扩展管理门户,右键单击 已发布的扩展,然后选择“ 证书”。
警告
扩展中的作用域更改会导致证书更改。 如果对范围进行更改,则需要新的扩展密钥。
生成令牌以提供给您的服务
Core SDK
getAppToken方法返回一个 Promise 对象,当该 Promise 对象完成解析时,其中包含一个由您的扩展证书签名的令牌。import * as SDK from "azure-devops-extension-sdk"; import { getAppToken } from "azure-devops-extension-sdk"; SDK.init(); getAppToken().then((token) => { // Add token to your request console.log(token); });将此令牌作为查询参数或请求标头传递给服务。
分析和验证令牌
下面是分析令牌的示例。 首先,从发布者页面下载和存储扩展的机密。 此机密必须可供应用程序使用。
.NET Framework
执行以下任务以添加一个引用以获取要编译的示例。
打开 NuGet 包管理器并添加对 System.IdentityModel.Tokens.Jwt 的引用。 此示例是使用此包版本 6.8.0 生成的。
using System;
using System.IdentityModel.Tokens.Jwt;
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.Encoding.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);
// Use the principal object as needed
Console.WriteLine(principal.Identity.Name);
}
}
}
.NET Core - WebAPI
执行以下任务以添加一个代码引用来使示例得以编译。
打开 NuGet 包管理器,并添加对 System.IdentityModel.Tokens.Jwt 的引用。 此示例是使用此包版本 5.1.4 生成的。
Startup.cs
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
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.AddControllers();
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, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseAuthorization();
app.UseRouting();
app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
API 控制器:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[Authorize]
public class SampleLogicController : ControllerBase
{
// ...
}