Работа с удостоверениями пользователей при проверке подлинности в Службе приложений Azure
В этой статье показано, как работать с удостоверениями пользователей при использовании встроенной проверки подлинности и авторизации в Служба приложений.
Доступ к утверждениям пользователей в коде приложения
Для всех языковых платформ Служба приложений делает утверждения во входящем токене (поступающем от пользователя, прошедшего проверку подлинности, или клиентского приложения) доступными для вашего кода путем их внедрения в заголовки запроса. Внешние запросы не могут задавать эти заголовки, поэтому они присутствуют только в том случае, если задано Служба приложений. Некоторые примеры заголовков включают:
Header | Описание |
---|---|
X-MS-CLIENT-PRINCIPAL |
Представление доступных утверждений в формате JSON в кодировке Base64. Дополнительные сведения см. в разделе Декодирование заголовка субъекта-клиента. |
X-MS-CLIENT-PRINCIPAL-ID |
Идентификатор вызывающего объекта, заданного поставщиком удостоверений. |
X-MS-CLIENT-PRINCIPAL-NAME |
Понятное имя вызывающего объекта, заданное поставщиком удостоверений, например Email Адрес, Имя участника-пользователя. |
X-MS-CLIENT-PRINCIPAL-IDP |
Имя поставщика удостоверений, используемого для проверки подлинности Служба приложений. |
Маркеры поставщика также предоставляются через аналогичные заголовки. Например, поставщик удостоверений Майкрософт также задает 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": ""
}
Свойство | Тип | Описание |
---|---|---|
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