Проверка маркера удостоверения Exchange
Важно!
Устаревшие токены Exchange устарели. Начиная с февраля 2025 г. мы начнем отключать устаревшие удостоверения пользователя Exchange и маркеры обратного вызова для Exchange Online клиентов. Временная шкала и подробные сведения см. на странице часто задаваемых вопросов. Это часть инициативы Майкрософт по обеспечению безопасности в будущем, которая предоставляет организациям средства, необходимые для реагирования на текущую среду угроз. Маркеры удостоверений пользователей Exchange по-прежнему будут работать в локальной среде Exchange. Проверка подлинности вложенных приложений — это рекомендуемый подход к токенам в будущем.
Надстройка Outlook может отправить вам маркер удостоверения пользователя Exchange, но прежде чем обращаться с запросом как с доверенным, нужно проверить, поступил ли маркер с ожидаемого сервера Exchange Server. Маркеры удостоверений пользователей Exchange представляют собой маркеры JSON Web Token (JWT). Инструкции по проверке JWT представлены в документе RFC 7519 JSON Web Token (JWT).
Рекомендуем использовать процесс, состоящий из четырех этапов, для проверки маркера удостоверения и получения уникального идентификатора пользователя. Первый этап: извлечение веб-маркера JSON (JWT) из строки, закодированной в формате URL-адреса Base64. Второй этап: проверка правильности маркера, то есть его предназначения для вашей надстройки Outlook, его актуальности и возможности извлечения допустимого URL-адреса для документа метаданных проверки подлинности. Затем необходимо получить документ метаданных проверки подлинности с сервера Exchange и проверить подпись, приложенную к маркеру удостоверения. Наконец, вычислить уникальный идентификатор пользователя путем объединения идентификатора Exchange пользователя с URL-адресом документа метаданных проверки подлинности.
Извлечение маркера JSON Web Token
Маркер, возвращаемый методом getUserIdentityTokenAsync, — это закодированная строка, представляющая его. В этом формате (согласно стандарту RFC 7519) все маркеры JWT состоят из трех частей, разделенных точками. Используется приведенный ниже формат.
{header}.{payload}.{signature}
Чтобы получить представление каждой части в формате JSON, необходимо раскодировать заголовок и полезные данные согласно кодировке Base64. Подпись необходимо расшифровать согласно кодировке Base64, чтобы получить массив байтов, содержащий двоичную подпись.
Дополнительные сведения о содержимом маркера см. в статье Подробные сведения о маркере удостоверения Exchange.
После получения трех раскодированных компонентов можно продолжать проверку содержимого маркера.
Проверка содержимого маркера
Чтобы проверить содержимое маркера, необходимо проверка следующее:
Проверьте заголовок и убедитесь, что:
-
typ
Для утверждения задано значениеJWT
. -
alg
Для утверждения задано значениеRS256
. -
x5t
утверждение присутствует.
-
Проверьте полезные данные и убедитесь, что:
-
amurl
Утверждение внутриappctx
задается в расположение файла манифеста ключа для подписи маркера. Например, ожидаемоеamurl
значение для Microsoft 365 — https://outlook.office365.com:443/autodiscover/metadata/json/1. Дополнительные сведения см. в следующем разделе Проверка домена . - Текущее время находится между временем, указанным в утверждениях
nbf
иexp
. В утвержденииnbf
указано время, с которого начинается срок действия маркера, а в утвержденииexp
— время его окончания. Рекомендуем допускать небольшие различия в заданном времени на разных серверах. -
aud
claim — это ожидаемый URL-адрес надстройки. -
version
Утверждение внутриappctx
утверждения имеет значениеExIdTok.V1
.
-
Проверка домена
При реализации логики проверки, описанной в предыдущем разделе, необходимо также требовать, чтобы домен amurl
утверждения соответствовал домену автообнаружения для пользователя. Для этого необходимо использовать или реализовать автообнаружения для Exchange.
Для Exchange Online убедитесь, что
amurl
является хорошо известным доменом (https://outlook.office365.com:443/autodiscover/metadata/json/1) или принадлежит к географическому или специальному облаку (Office 365 URL-адресам и диапазонам IP-адресов).Если у вашей службы надстроек уже существует конфигурация с клиентом пользователя, можно установить, является ли это
amurl
доверенным.Для гибридного развертывания Exchange используйте автообнаружения на основе OAuth, чтобы проверить домен, ожидаемый для пользователя. Однако, хотя пользователю потребуется пройти проверку подлинности в рамках потока автообнаружения, надстройка никогда не должна собирать учетные данные пользователя и выполнять обычную проверку подлинности.
Если надстройка не может проверить amurl
с помощью какого-либо из этих параметров, вы можете правильно завершить работу надстройки с соответствующим уведомлением для пользователя, если проверка подлинности необходима для рабочего процесса надстройки.
Проверка подписи маркера удостоверения
Когда вы убедитесь, что JWT содержит необходимые утверждения, можно переходить к проверке подписи маркера.
Получение открытого ключа подписывания
Первый этап — получение открытого ключа, соответствующего сертификату, который сервер Exchange Server использовал для подписывания маркера. Этот ключ указан в документе с метаданными проверки подлинности. Этот документ представляет собой JSON-файл, размещенный по URL-адресу, указанному в утверждении amurl
.
Документ с метаданными проверки подлинности имеет приведенный ниже формат.
{
"id": "_70b34511-d105-4e2b-9675-39f53305bb01",
"version": "1.0",
"name": "Exchange",
"realm": "*",
"serviceName": "00000002-0000-0ff1-ce00-000000000000",
"issuer": "00000002-0000-0ff1-ce00-000000000000@*",
"allowedAudiences": [
"00000002-0000-0ff1-ce00-000000000000@*"
],
"keys": [
{
"usage": "signing",
"keyinfo": {
"x5t": "enh9BJrVPU5ijV1qjZjV-fL2bco"
},
"keyvalue": {
"type": "x509Certificate",
"value": "MIIHNTCC..."
}
}
],
"endpoints": [
{
"location": "https://by2pr06mb2229.namprd06.prod.outlook.com:444/autodiscover/metadata/json/1",
"protocol": "OAuth2",
"usage": "metadata"
}
]
}
Доступные ключи подписывания находятся в массиве keys
. Выберите подходящий ключ, убедившись, что значение x5t
в свойстве keyinfo
совпадает со значением x5t
в заголовке маркера. Открытый ключ находится в дочернем свойстве value
свойства keyvalue
, хранящемся в массиве байтов с кодировкой Base64.
После получения правильного открытого ключа проверьте подпись. Подписанные данные представляют собой первые две части закодированного маркера, разделенные точкой:
{header}.{payload}
Вычисление уникального идентификатора для учетной записи Exchange
Создайте уникальный идентификатор для учетной записи Exchange, объединив URL-адрес документа метаданных проверки подлинности с идентификатором Exchange для учетной записи. При наличии этого уникального идентификатора используйте его для создания системы единого входа (SSO) для веб-службы надстройки Outlook. Дополнительные сведения об использовании уникального идентификатора для единого входа см. в статье Проверка подлинности пользователя с помощью маркера удостоверения для Exchange.
Проверка маркера с помощью библиотеки
Существует ряд библиотек, способных выполнять общие задачи анализа и проверки JWT. Корпорация Майкрософт предоставляет библиотеку System.IdentityModel.Tokens.Jwt
, которую можно использовать для проверки маркеров удостоверений пользователей Exchange.
Важно!
Мы больше не рекомендуем управляемый API веб-служб Exchange, так как Microsoft.Exchange.WebServices.Auth.dll, хотя по-прежнему доступен, теперь устарел и использует неподдерживаемые библиотеки, такие как Microsoft.IdentityModel.Extensions.dll.
System.IdentityModel.Tokens.Jwt
Библиотека System.IdentityModels.Tokens.Jwt может анализировать маркер, а также выполнять проверку, но вам потребуется самостоятельно проанализировать утверждение appctx
и получить открытый ключ подписывания.
// Load the encoded token
string encodedToken = "...";
JwtSecurityToken jwt = new JwtSecurityToken(encodedToken);
// Parse the appctx claim to get the auth metadata url
string authMetadataUrl = string.Empty;
var appctx = jwt.Claims.FirstOrDefault(claim => claim.Type == "appctx");
if (appctx != null)
{
var AppContext = JsonConvert.DeserializeObject<ExchangeAppContext>(appctx.Value);
// Token version check
if (string.Compare(AppContext.Version, "ExIdTok.V1", StringComparison.InvariantCulture) != 0) {
// Fail validation
}
authMetadataUrl = AppContext.MetadataUrl;
}
// Use System.IdentityModel.Tokens.Jwt library to validate standard parts
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters tvp = new TokenValidationParameters();
tvp.ValidateIssuer = false;
tvp.ValidateAudience = true;
tvp.ValidAudience = "{URL to add-in}";
tvp.ValidateIssuerSigningKey = true;
// GetSigningKeys downloads the auth metadata doc and
// returns a List<SecurityKey>
tvp.IssuerSigningKeys = GetSigningKeys(authMetadataUrl);
tvp.ValidateLifetime = true;
try
{
var claimsPrincipal = tokenHandler.ValidateToken(encodedToken, tvp, out SecurityToken validatedToken);
// If no exception, all standard checks passed
}
catch (SecurityTokenValidationException ex)
{
// Validation failed
}
Класс ExchangeAppContext
определяется следующим образом:
using Newtonsoft.Json;
/// <summary>
/// Representation of the appctx claim in an Exchange user identity token.
/// </summary>
public class ExchangeAppContext
{
/// <summary>
/// The Exchange identifier for the user
/// </summary>
[JsonProperty("msexchuid")]
public string ExchangeUid { get; set; }
/// <summary>
/// The token version
/// </summary>
public string Version { get; set; }
/// <summary>
/// The URL to download authentication metadata
/// </summary>
[JsonProperty("amurl")]
public string MetadataUrl { get; set; }
}
Пример проверки маркеров Exchange с помощью этой библиотеки, в котором также реализован метод GetSigningKeys
: Outlook-Add-In-Token-Viewer.
См. также
Office Add-ins