Trabalhar com identidades de usuário na autenticação do Serviço de Aplicativo do Azure
Este artigo mostra como trabalhar com identidades de usuário ao usar a autenticação e a autorização internas no Serviço de Aplicativo.
Acessar declarações de usuário no código do aplicativo
Em todas as estruturas de linguagem, o Serviço de Aplicativo disponibiliza as declarações no token de entrada (seja de um usuário final autenticado ou de um aplicativo cliente) para o seu código injetando-as nos cabeçalhos de solicitação. Solicitações externas não são permitidas para definir esses cabeçalhos, portanto são apresentadas somente se definido pelo Serviço de Aplicativo. Alguns cabeçalhos de exemplo incluem:
parâmetro | Descrição |
---|---|
X-MS-CLIENT-PRINCIPAL |
Uma representação JSON codificada em Base64 de declarações disponíveis. Para obter mais informações, confira Como decodificar o cabeçalho da entidade de segurança do cliente. |
X-MS-CLIENT-PRINCIPAL-ID |
Um identificador para o chamador definido pelo provedor de identidade. |
X-MS-CLIENT-PRINCIPAL-NAME |
Um nome legível para o chamador definido pelo provedor de identidade, como endereço de email ou nome principal do usuário. |
X-MS-CLIENT-PRINCIPAL-IDP |
O nome do provedor de identidade usado pela Autenticação do Serviço de Aplicativo. |
Os tokens de provedor também são expostos por meio de cabeçalhos semelhantes. Por exemplo, o Microsoft Entra também define X-MS-TOKEN-AAD-ACCESS-TOKEN
e X-MS-TOKEN-AAD-ID-TOKEN
, conforme apropriado.
Observação
Diferentes estruturas de linguagem podem apresentar esses cabeçalhos ao código do aplicativo em diferentes formatos, como letras minúsculas ou maiúsculas.
Um código escrito em qualquer linguagem ou estrutura pode obter as informações necessárias desses cabeçalhos. O artigo Como decodificar o cabeçalho da entidade de segurança do cliente aborda esse processo. Para algumas estruturas, a plataforma também fornece opções adicionais que podem ser mais convenientes.
Como decodificar o cabeçalho da entidade de segurança do cliente
X-MS-CLIENT-PRINCIPAL
contém o conjunto completo de declarações disponíveis como JSON codificado em Base64. Essas declarações passam por um processo de mapeamento de declarações padrão, portanto, algumas podem ter nomes diferentes do que você veria se processasse o token diretamente. O conteúdo da resposta é estrutura conforme a seguir:
{
"auth_typ": "",
"claims": [
{
"typ": "",
"val": ""
}
],
"name_typ": "",
"role_typ": ""
}
Propriedade | Type | Descrição |
---|---|---|
auth_typ |
string | O nome do provedor de identidade usado pela Autenticação do Serviço de Aplicativo. |
claims |
matriz de objetos | Uma matriz de objetos que representam as declarações disponíveis. Cada objeto contém as propriedades typ e val . |
typ |
string | O nome da declaração. Isso pode estar sujeito ao mapeamento de declarações padrão e pode ser diferente da declaração correspondente contida em um token. |
val |
string | O valor da declaração. |
name_typ |
string | O tipo de declaração de nome, que normalmente é um URI que fornece informações de esquema sobre a declaração name se houver uma definida. |
role_typ |
string | O tipo de declaração de nome, que normalmente é um URI que fornece informações de esquema sobre a declaração role se houver uma definida. |
Para processar esse cabeçalho, seu aplicativo precisará decodificar o conteúdo e iterar pela matriz claims
para localizar as declarações de interesse. Pode ser conveniente a conversão em uma representação usada pela estrutura de linguagem do aplicativo. Aqui está um exemplo desse processo em C# que constrói um tipo ClaimsPrincipal para o aplicativo usar:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;
public static class ClaimsPrincipalParser
{
private class ClientPrincipalClaim
{
[JsonPropertyName("typ")]
public string Type { get; set; }
[JsonPropertyName("val")]
public string Value { get; set; }
}
private class ClientPrincipal
{
[JsonPropertyName("auth_typ")]
public string IdentityProvider { get; set; }
[JsonPropertyName("name_typ")]
public string NameClaimType { get; set; }
[JsonPropertyName("role_typ")]
public string RoleClaimType { get; set; }
[JsonPropertyName("claims")]
public IEnumerable<ClientPrincipalClaim> Claims { get; set; }
}
public static ClaimsPrincipal Parse(HttpRequest req)
{
var principal = new ClientPrincipal();
if (req.Headers.TryGetValue("x-ms-client-principal", out var header))
{
var data = header[0];
var decoded = Convert.FromBase64String(data);
var json = Encoding.UTF8.GetString(decoded);
principal = JsonSerializer.Deserialize<ClientPrincipal>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
/**
* At this point, the code can iterate through `principal.Claims` to
* check claims as part of validation. Alternatively, we can convert
* it into a standard object with which to perform those checks later
* in the request pipeline. That object can also be leveraged for
* associating user data, etc. The rest of this function performs such
* a conversion to create a `ClaimsPrincipal` as might be used in
* other .NET code.
*/
var identity = new ClaimsIdentity(principal.IdentityProvider, principal.NameClaimType, principal.RoleClaimType);
identity.AddClaims(principal.Claims.Select(c => new Claim(c.Type, c.Value)));
return new ClaimsPrincipal(identity);
}
}
Alternativas específicas da estrutura
Para aplicativos ASP.NET 4.6, o Serviço de Aplicativo preenche ClaimsPrincipal.Current com as declarações do usuário autenticado, de modo que seja possível seguir o padrão de código .NET Standard, incluindo o atributo [Authorize]
. Da mesma forma, para aplicativos PHP, o Serviço de Aplicativo preenche a variável _SERVER['REMOTE_USER']
. Para aplicativos Java, as declarações podem ser acessadas por meio do servlet do Tomcat.
Para o Azure Functions, ClaimsPrincipal.Current
não é preenchido para o código .NET, mas você ainda pode encontrar as declarações do usuário nos cabeçalhos da solicitação ou obter o objeto ClaimsPrincipal
por meio do contexto da solicitação ou mesmo por meio de um parâmetro de associação. Para obter mais informações, confira Trabalhando com identidades de cliente no Azure Functions.
No caso do .NET Core, o Microsoft.Identity.Web oferece suporte à população do usuário atual com a autenticação do Serviço de Aplicativo. Para saber mais, você pode ler sobre isso no wiki Microsoft.Identity.Web ou vê-lo demonstrado neste tutorial para um aplicativo Web acessando o Microsoft Graph.
Observação
Para que o mapeamento das declarações funcione, você deve habilitar o Token Store.
Acessar declarações de usuário usando a API
Se o repositório de token estiver habilitado para seu aplicativo, você também poderá obter outros detalhes sobre o usuário autenticado chamando /.auth/me
.