Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Note
Nem todos os clientes têm permissão para obter certificados MTLS PoP porque esse recurso está atualmente em versão prévia privada.
A associação de token de certificado (também conhecida como mTLS PoP – Prova de Posse de TLS Mútua) é um recurso de segurança avançado que associa criptograficamente tokens de acesso a um certificado X.509 específico. O RFC 8705 descreve essa associação. A associação garante que, mesmo que um token seja interceptado, um invasor não poderá usá-lo sem a posse da chave privada correspondente.
Entender como a associação de token funciona
As etapas a seguir descrevem o fluxo de vinculação de token desde a aquisição até a verificação.
- Token Acquisition: ao solicitar um token de acesso com a associação de token habilitada, Microsoft Identity Web inclui a impressão digital do certificado na solicitação de token
-
Associação de token: o servidor de autorização insere uma
cnfdeclaração (confirmação) no token emitido que contém a impressão digital SHA-256 do certificado (x5t#S256) - Chamada à API: o cliente apresenta o token associado e o certificado ao chamar a API downstream
-
Verificação: a API valida que o certificado apresentado corresponde à referência de certificado na declaração do
cnftoken
sequenceDiagram
participant Client
participant EntraID as Microsoft Entra ID
participant API
Client->>EntraID: Token request with certificate thumbprint
EntraID->>Client: Token with cnf claim (bound to certificate)
Client->>API: MTLS_POP token + Client certificate
API->>API: Validate token and certificate binding
API->>Client: Protected resource
Examinar os benefícios de segurança
A associação de token fornece as seguintes vantagens para proteger seus aplicativos.
- Proteção contra roubo de token: tokens roubados são inúteis sem o certificado correspondente
- Prevenção de ataque de repetição: os tokens não podem ser utilizados a partir de clientes diferentes
- Autenticação Aprimorada: combina "algo que você tem" (certificado) com fluxos OAuth2 tradicionais
- Confiança Zero Architecture: alinha-se com princípios zero trust associando credenciais a dispositivos específicos
Configurar associação de token
Configure o aplicativo cliente e o servidor de API para habilitar a associação de token poP do mTLS.
Configurar o aplicativo do cliente
Conclua as etapas a seguir para configurar o aplicativo cliente para associação de token.
1. Definir configurações de Microsoft Entra ID
Em seu appsettings.json, defina suas configurações de Microsoft Entra incluindo o certificado:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientCredentials": [
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=YourCertificate"
}
],
"SendX5c": true
}
}
2. Configurar a API downstream com associação de token
Configure sua seção de API downstream com o MTLS_POP esquema de protocolo:
{
"DownstreamApi": {
"BaseUrl": "https://api.contoso.com/",
"RelativePath": "api/data",
"ProtocolScheme": "MTLS_POP",
"RequestAppToken": true,
"Scopes": [ "api://your-api-scope/.default" ]
}
}
Propriedades de configuração importantes:
-
ProtocolScheme: deve ser definido para"MTLS_POP"habilitar a associação de token -
RequestAppToken: deve sertrue(a associação de token atualmente dá suporte apenas a tokens de aplicativo) -
Scopes: escopos de API necessários para a chamada à API downstream
3. Registrar serviços
Registre o serviço de API downstream no código de inicialização do aplicativo. O exemplo a seguir mostra abordagens de aplicativo de console e ASP.NET Core.
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Option 1: Using TokenAcquirerFactory (for console apps, background services)
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi(
"DownstreamApi",
tokenAcquirerFactory.Configuration.GetSection("DownstreamApi"));
var serviceProvider = tokenAcquirerFactory.Build();
// Option 2: Using ASP.NET Core DI (for web apps, web APIs)
builder.Services.AddAuthentication()
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddDownstreamApi(
"DownstreamApi",
builder.Configuration.GetSection("DownstreamApi"));
Configurar o servidor de API
A API downstream deve validar o token e a associação de certificado. Aqui está um exemplo completo:
1. Registrar manipuladores de autenticação
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add standard JWT Bearer authentication
builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);
// Add custom MTLS_POP authentication handler
builder.Services.AddAuthentication()
.AddScheme<AuthenticationSchemeOptions, MtlsPopAuthenticationHandler>(
"MTLS_POP",
options => { });
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
2. Implementar o manipulador de autenticação PoP do mTLS
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text.Encodings.Web;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
public class MtlsPopAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public const string ProtocolScheme = "MTLS_POP";
public MtlsPopAuthenticationHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder)
: base(options, logger, encoder)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// 1. Extract the MTLS_POP authorization header
var authHeader = Request.Headers.Authorization.FirstOrDefault();
if (string.IsNullOrEmpty(authHeader) ||
!authHeader.StartsWith($"{ProtocolScheme} ", StringComparison.OrdinalIgnoreCase))
{
return AuthenticateResult.NoResult();
}
var authToken = authHeader.Substring($"{ProtocolScheme} ".Length).Trim();
try
{
// 2. Parse the JWT token
var handler = new JsonWebTokenHandler();
var token = handler.ReadJsonWebToken(authToken);
// 3. Extract the 'cnf' claim
var cnfClaim = token.Claims.FirstOrDefault(c => c.Type == "cnf");
if (cnfClaim == null)
{
return AuthenticateResult.Fail("Missing 'cnf' claim in MTLS_POP token");
}
// 4. Extract certificate thumbprint from cnf claim
var cnfJson = JsonDocument.Parse(cnfClaim.Value);
if (!cnfJson.RootElement.TryGetProperty("x5t#S256", out var x5tS256Element))
{
return AuthenticateResult.Fail("Missing 'x5t#S256' in cnf claim");
}
var expectedThumbprint = x5tS256Element.GetString();
// 5. Get client certificate from TLS connection
var clientCert = Context.Connection.ClientCertificate;
if (clientCert != null)
{
var actualThumbprint = GetCertificateThumbprint(clientCert);
// 6. Validate certificate binding
if (!string.Equals(actualThumbprint, expectedThumbprint,
StringComparison.OrdinalIgnoreCase))
{
return AuthenticateResult.Fail(
"Certificate thumbprint mismatch with cnf claim");
}
}
// 7. Create claims principal
var claims = token.Claims.Select(c => new Claim(c.Type, c.Value)).ToList();
var identity = new ClaimsIdentity(claims, ProtocolScheme);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, ProtocolScheme);
return AuthenticateResult.Success(ticket);
}
catch (Exception ex)
{
Logger.LogError(ex, "Error validating mTLS PoP token");
return AuthenticateResult.Fail($"Validation error: {ex.Message}");
}
}
private static string GetCertificateThumbprint(X509Certificate2 certificate)
{
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(certificate.RawData);
return Base64UrlEncoder.Encode(hash);
}
}
Usar associação de token em aplicativos
Os exemplos a seguir mostram como integrar a associação de token poP do mTLS em diferentes tipos de aplicativo.
Chamar APIs a partir de um aplicativo de console ou daemon
O exemplo a seguir demonstra um aplicativo de console ou daemon que chama uma API downstream com vinculação de token PoP mTLS.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
public class Program
{
public static async Task Main(string[] args)
{
// Create and configure token acquirer
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi(
"SecureApi",
tokenAcquirerFactory.Configuration.GetSection("SecureApi"));
var serviceProvider = tokenAcquirerFactory.Build();
// Get IDownstreamApi instance
var downstreamApi = serviceProvider.GetRequiredService<IDownstreamApi>();
// Call API with mTLS PoP token
var response = await downstreamApi.GetForAppAsync<ApiResponse>("SecureApi");
Console.WriteLine($"Result: {response?.Data}");
}
}
public class ApiResponse
{
public string? Data { get; set; }
}
Chamar APIs de um aplicativo Web ASP.NET Core
O exemplo a seguir mostra um controlador que chama uma API downstream com vinculação de token PoP mTLS.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Abstractions;
[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
private readonly IDownstreamApi _downstreamApi;
private readonly ILogger<DataController> _logger;
public DataController(
IDownstreamApi downstreamApi,
ILogger<DataController> logger)
{
_downstreamApi = downstreamApi;
_logger = logger;
}
[HttpGet]
public async Task<IActionResult> GetSecureData()
{
try
{
// Call downstream API with mTLS PoP token binding
var data = await _downstreamApi.GetForAppAsync<SecureData>(
"SecureApi");
return Ok(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to retrieve secure data");
return StatusCode(500, "Failed to retrieve data");
}
}
}
public class SecureData
{
public string? Id { get; set; }
public string? Value { get; set; }
}
Configurar DownstreamApiOptions programmaticamente
O exemplo a seguir define as opções de PoP do mTLS diretamente no código em vez de arquivos de configuração.
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
public class SecureApiService
{
private readonly IDownstreamApi _downstreamApi;
public SecureApiService(IDownstreamApi downstreamApi)
{
_downstreamApi = downstreamApi;
}
public async Task<T?> CallSecureApiAsync<T>(string endpoint) where T : class
{
return await _downstreamApi.GetForAppAsync<T>(
serviceName: null,
downstreamApiOptionsOverride: options =>
{
options.BaseUrl = "https://api.secure.com";
options.RelativePath = endpoint;
options.ProtocolScheme = "MTLS_POP";
options.RequestAppToken = true;
options.Scopes = new[] { "api://secure-api/.default" };
});
}
}
Usar MicrosoftIdentityMessageHandler com associação de token
MicrosoftIdentityMessageHandler dá suporte à associação de token PoP mTLS por meio dos métodos de extensão AddMicrosoftIdentityMessageHandler. Quando ProtocolScheme é definido como "MTLS_POP", o manipulador adquire automaticamente um token associado e envia solicitações por meio de um cliente HTTP configurado pelo mTLS.
Configurar opções integradas
O exemplo a seguir registra um cliente HTTP com configuração de PoP mTLS embutida e mostra seu uso em um serviço.
// Program.cs
services.AddHttpClient("MtlsPopClient", client =>
{
client.BaseAddress = new Uri("https://api.contoso.com");
})
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://contoso/.default");
options.ProtocolScheme = "MTLS_POP";
options.RequestAppToken = true;
});
// Usage in a service
public class SecureApiService
{
private readonly HttpClient _httpClient;
public SecureApiService(IHttpClientFactory factory)
{
_httpClient = factory.CreateClient("MtlsPopClient");
}
public async Task<string> GetSecureDataAsync()
{
// Authentication and mTLS certificate binding are automatic
var response = await _httpClient.GetAsync("/api/secure-data");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
Carregar configurações de appsettings.json
Você também pode carregar as configurações de associação de token do arquivo de configuração.
appsettings.json:
{
"DownstreamApis": {
"SecureApi": {
"Scopes": ["api://secure-api/.default"],
"ProtocolScheme": "MTLS_POP",
"RequestAppToken": true
}
}
}
Program.cs: o código a seguir registra o cliente HTTP usando a seção de configuração.
services.AddHttpClient("SecureApiClient", client =>
{
client.BaseAddress = new Uri("https://secure-api.example.com");
})
.AddMicrosoftIdentityMessageHandler(
configuration.GetSection("DownstreamApis:SecureApi"),
"SecureApi");
Aplicar vinculação de token por solicitação
Use opções por solicitação quando algumas solicitações precisarem de associação de token e outras não:
services.AddHttpClient("FlexibleClient")
.AddMicrosoftIdentityMessageHandler();
// In a service:
public async Task<string> CallWithTokenBindingAsync()
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.contoso.com/secure")
.WithAuthenticationOptions(options =>
{
options.Scopes.Add("api://contoso/.default");
options.ProtocolScheme = "MTLS_POP";
options.RequestAppToken = true;
});
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Para obter mais informações sobre MicrosoftIdentityMessageHandler, consulte a documentação de APIs personalizadas.
Criar um HttpClient customizado com um provedor de cabeçalho de autorização
Use essa abordagem para cenários que exigem mais controle sobre solicitações HTTP. O exemplo a seguir adquire um cabeçalho de autorização associado e cria um cliente HTTP configurado por mTLS.
using Microsoft.Identity.Abstractions;
using System.Net.Http.Headers;
public class CustomApiClient
{
private readonly IAuthorizationHeaderProvider _authProvider;
private readonly IHttpClientFactory _httpClientFactory;
public CustomApiClient(
IAuthorizationHeaderProvider authProvider,
IHttpClientFactory httpClientFactory)
{
_authProvider = authProvider;
_httpClientFactory = httpClientFactory;
}
public async Task<string> CallApiWithCustomLogicAsync()
{
// Create downstream API options for mTLS PoP
var apiOptions = new DownstreamApiOptions
{
BaseUrl = "https://api.contoso.com",
ProtocolScheme = "MTLS_POP",
RequestAppToken = true,
Scopes = new[] { "api://contoso/.default" }
};
// Get authorization header with binding certificate info
var authResult = await (_authProvider as IBoundAuthorizationHeaderProvider)
?.CreateBoundAuthorizationHeaderAsync(apiOptions)!;
if (authResult.IsSuccess)
{
// Create HTTP client with certificate binding
var httpClient = authResult.Value.BindingCertificate != null
? CreateMtlsHttpClient(authResult.Value.BindingCertificate)
: _httpClientFactory.CreateClient();
// Set authorization header
httpClient.DefaultRequestHeaders.Authorization =
AuthenticationHeaderValue.Parse(authResult.Value.AuthorizationHeaderValue);
// Make API call
var response = await httpClient.GetAsync(
$"{apiOptions.BaseUrl}/api/endpoint");
return await response.Content.ReadAsStringAsync();
}
throw new InvalidOperationException("Failed to acquire token");
}
private HttpClient CreateMtlsHttpClient(X509Certificate2 certificate)
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
return new HttpClient(handler);
}
}
Examinar a estrutura do token
Os exemplos a seguir mostram como os tokens padrão e associados diferem.
Comparar tokens padrão do OAuth2
Um token OAuth2 padrão não contém informações de associação de certificado.
{
"aud": "api://your-api",
"iss": "https://login.microsoftonline.com/tenant-id/",
"iat": 1234567890,
"exp": 1234571490,
"appid": "client-id",
"tid": "tenant-id"
}
Revisar tokens de PoP do mTLS com vinculação
Um token pop mTLS inclui a cnf declaração que associa o token a um certificado específico.
{
"aud": "api://your-api",
"iss": "https://login.microsoftonline.com/tenant-id/",
"iat": 1234567890,
"exp": 1234571490,
"appid": "client-id",
"tid": "tenant-id",
"cnf": {
"x5t#S256": "buc7x2HxS_hPnVJb9J5mwPr6jCw8Y_2LHDz-gp_-6KM"
}
}
A cnf declaração (confirmação) contém a impressão digital SHA-256 do certificado, codificada em Base64Url.
Entender as limitações atuais
Revise as restrições a seguir antes de implementar a vinculação de token PoP do mTLS.
Dar suporte somente a tokens de aplicativo
A associação de token atualmente dá suporte apenas a tokens de aplicativo (somente aplicativo). Não há suporte para tokens delegados de usuário.
Definir o esquema de protocolo
A propriedade ProtocolScheme deve ser definida explicitamente como "MTLS_POP" para habilitar a vinculação de token. Se não for definido, a autenticação de portador padrão será usada.
Atender aos requisitos de certificado
- O certificado deve ser configurado
ClientCredentialscomSendX5cdefinido paratrue - O certificado deve estar acessível no momento da aquisição do token
Solucionar problemas comuns
Use as diretrizes a seguir para diagnosticar e resolver problemas de associação de token.
Resolver problemas comuns
1. "Declaração 'cnf' ausente no token"
Causa: a associação de token não foi configurada corretamente ou o token é um token de portador padrão.
Solução: verifique se o ProtocolScheme está definido como "MTLS_POP" e se o RequestAppToken está true.
{
"DownstreamApi": {
"ProtocolScheme": "MTLS_POP", // ensure this is set
"RequestAppToken": true
}
}
2. "Incompatibilidade de impressão digital do certificado"
Causa: o certificado apresentado à API não corresponde ao usado para aquisição de token.
Solução:
- Verifique se o mesmo certificado é usado para aquisição de token e chamadas à API
- Verificar a configuração de carregamento de certificado em
ClientCredentials - Verifique se o certificado não expirou ou foi renovado
3. "Um certificado, que é necessário para associação de token, está ausente"
Cause: nenhum certificado está configurado nas configurações de Microsoft Entra.
Solução: adicione um certificado à sua ClientCredentials configuração e defina SendX5c como true.
{
"AzureAd": {
"ClientCredentials": [
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=YourCertificate"
}
],
"SendX5c": true // required for token binding
}
}
4. "A associação de token requer a aquisição de token de aplicativo habilitada"
Causa: RequestAppToken não está definido como true.
Solução: defina RequestAppTokentrue em suas opções.
var options = new DownstreamApiOptions
{
ProtocolScheme = "MTLS_POP",
RequestAppToken = true, // must be true
};
Vinculação de token de depuração
Use as técnicas a seguir para investigar problemas de associação de token.
Habilitar registro em log detalhado
Adicione a configuração a seguir para habilitar o registro em log no nível de depuração para Microsoft. Identity.Web.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug"
}
}
}
Inspecionar declarações de token
Use o código a seguir para listar todas as declarações em um token e verificar a cnf declaração.
var handler = new JsonWebTokenHandler();
var token = handler.ReadJsonWebToken(tokenString);
foreach (var claim in token.Claims)
{
Console.WriteLine($"{claim.Type}: {claim.Value}");
}
// Look for 'cnf' claim with x5t#S256
var cnfClaim = token.Claims.FirstOrDefault(c => c.Type == "cnf");
Verificar a impressão digital do certificado
Use o código a seguir para calcular e exibir a impressão digital SHA-256 de um certificado para comparação.
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.IdentityModel.Tokens;
var cert = new X509Certificate2("path/to/cert.pfx", "password");
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(cert.RawData);
var thumbprint = Base64UrlEncoder.Encode(hash);
Console.WriteLine($"Certificate thumbprint: {thumbprint}");
Siga as diretrizes de segurança
Aplique as seguintes práticas de segurança ao implementar a associação de token.
Gerenciar certificados com segurança
- Armazenar com segurança: Use o Azure Key Vault ou repositórios de certificados seguros
- Girar regularmente: implementar procedimentos de rotação de certificados
- Monitorar a expiração: configurar alertas para a expiração do certificado
- Restringir o acesso: limitar quem pode acessar chaves privadas de certificado
Proteger conexões de rede
- Exigir TLS 1.2+: verifique se todas as conexões usam versões modernas do TLS
- Validar certificados: implementar a validação de certificado adequada no servidor
- Usar criptografias fortes: configurar conjuntos de criptografia seguros
Manipular tokens com segurança
- Tempos de vida curtos: usar tokens de curta duração (recomendado: 1 hora)
- Armazenamento adequado: nunca registre ou exponha tokens
- Validar minuciosamente: verificar todas as declarações, a expiração e a vinculação
Seguir as práticas recomendadas
Ao implantar a vinculação de token PoP do mTLS, tenha em mente as seguintes recomendações.
- Sempre use HTTPS: mTLS PoP requer transporte seguro
- Use um certificado que armazene o material de chave privada no hardware, por exemplo, no TPM: Use um hardware em vez de segurança de software para melhor proteção.
- Implementar o tratamento de erros adequado: administrar de forma elegante erros de certificado e token
- Monitorar a expiração do certificado: automatizar a renovação do certificado
- Usar certificados separados por ambiente: Certificados de desenvolvimento, preparo e produção
- Eventos de segurança de log: rastrear falhas de associação de token e incompatibilidades de certificado
- Testar a rotação de certificados: verifique se o aplicativo lida com atualizações de certificado
- Documente sua configuração: manter a documentação clara dos requisitos de certificado
Conteúdo relacionado
- Documentação do Microsoft Identity Web
- Visão geral da chamada de APIs downstream
- Documentação de APIs personalizadas
- credenciais de certificado Microsoft Entra
- Autenticação de cliente do OAuth 2.0 Mutual-TLS
Explorar o código de exemplo
Amostras funcionais completas demonstrando a vinculação de token PoP do mTLS estão disponíveis no repositório:
-
Aplicativo cliente:
tests/DevApps/MtlsPop/MtlsPopClient -
Servidor de API Web:
tests/DevApps/MtlsPop/MtlsPopWebApi
Estes exemplos demonstram:
- Concluir a configuração do cliente e do servidor
- Aquisição de token com associação de certificado
- Implementação do manipulador de autenticação personalizada
- Validação de certificado e verificação de impressão digital