Работа с удостоверениями пользователей при проверке подлинности в Службе приложений Azure
В этой статье показано, как работать с удостоверениями пользователей при использовании встроенной проверки подлинности и авторизации в Служба приложений.
Доступ к утверждениям пользователей в коде приложения
Для всех языковых платформ Служба приложений делает утверждения во входящем токене (поступающем от пользователя, прошедшего проверку подлинности, или клиентского приложения) доступными для вашего кода путем их внедрения в заголовки запроса. Внешние запросы не могут задавать эти заголовки, поэтому они присутствуют только в том случае, если задано Служба приложений. Некоторые примеры заголовков включают:
Верхний колонтитул | Description |
---|---|
X-MS-CLIENT-PRINCIPAL |
Представление доступных утверждений в кодировке Base64 закодировано в формате JSON. Дополнительные сведения см. в разделе "Декодирование заголовка субъекта-клиента". |
X-MS-CLIENT-PRINCIPAL-ID |
Идентификатор вызывающего объекта, заданного поставщиком удостоверений. |
X-MS-CLIENT-PRINCIPAL-NAME |
Имя вызывающего абонента, заданное поставщиком удостоверений, например адрес электронной почты или имя участника-пользователя. |
X-MS-CLIENT-PRINCIPAL-IDP |
Имя поставщика удостоверений, используемого Служба приложений аутентификации. |
Маркеры поставщика также предоставляются с помощью аналогичных заголовков. Например, Microsoft Entra также задает X-MS-TOKEN-AAD-ACCESS-TOKEN
и X-MS-TOKEN-AAD-ID-TOKEN
по необходимости.
Примечание.
Различные языковые платформы могут представлять эти заголовки коду приложения в разных форматах, таких как строчные или заголовки.
Сведения из этих заголовков можно получить с помощью кода, написанного на любом языке или в любой платформе. Декодирование заголовка субъекта-клиента охватывает этот процесс. Для некоторых платформ платформа также предоставляет дополнительные возможности, которые могут быть более удобными.
Декодирование заголовка субъекта-клиента
X-MS-CLIENT-PRINCIPAL
содержит полный набор доступных утверждений в формате JSON в кодировке Base64. Эти утверждения проходят процесс сопоставления утверждений по умолчанию, поэтому некоторые из них могут иметь разные имена, отличные от того, если обработка маркера выполняется напрямую. Декодированные полезные данные структурированы следующим образом:
{
"auth_typ": "",
"claims": [
{
"typ": "",
"val": ""
}
],
"name_typ": "",
"role_typ": ""
}
Свойство | Type | Описание: |
---|---|---|
auth_typ |
строка | Имя поставщика удостоверений, используемого Служба приложений аутентификации. |
claims |
массив объектов | Массив объектов, представляющих доступные утверждения. Каждый объект содержит typ и val свойства. |
typ |
строка | Имя утверждения. Он может быть подвержен сопоставлению утверждений по умолчанию и может отличаться от соответствующего утверждения, содержащегося в токене. |
val |
строка | Значение утверждения. |
name_typ |
строка | Тип утверждения имени, который обычно является универсальным кодом ресурса (URI), предоставляющим сведения о схеме name утверждения, если он определен. |
role_typ |
строка | Тип утверждения роли, который обычно является универсальным кодом ресурса (URI), предоставляющим сведения о role схеме утверждения, если он определен. |
Чтобы обработать этот заголовок, приложение должно декодировать полезные данные и выполнять итерацию по claims
массиву, чтобы найти утверждения, интересующие вас. Их может быть удобно преобразовать в представление, используемое платформой языка приложения. Ниже приведен пример этого процесса в C#, который создает тип ClaimsPrincipal для используемого приложения:
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);
}
}
Альтернативные варианты для конкретной платформы
Для приложений ASP.NET 4.6 служба приложений заполняет свойство ClaimsPrincipal.Current утверждениями пользователя, прошедшими проверку подлинности, поэтому вы можете следовать стандартным шаблонам кода .NET, включая атрибут [Authorize]
. Аналогичным образом для приложений PHP служба приложений заполняет переменную _SERVER['REMOTE_USER']
. Для приложений Java утверждения доступны из сервлета Tomcat.
Для Функции AzureClaimsPrincipal.Current
код .NET не заполняется, но вы по-прежнему можете найти утверждения пользователя в заголовках запроса или получить ClaimsPrincipal
объект из контекста запроса или даже через параметр привязки. Дополнительные сведения см. в статье "Работа с удостоверениями клиентов" в Функции Azure.
При работе с .NET Core Microsoft.Identity.Web поддерживает заполнение текущего пользователя с использованием функции проверки подлинности Службы приложений. Дополнительные сведения см. на вики-сайте Microsoft.Identity.Web или в руководстве по веб-приложению, которое обращается к Microsoft Graph.
Примечание.
Чтобы сопоставление утверждений работало, необходимо включить хранилище токенов.
Доступ к утверждениям пользователей с помощью API
Если хранилище маркеров включено для приложения, вы также можете получить другие сведения о пользователе, прошедшем /.auth/me
проверку подлинности.