Поделиться через


Проверка маркера удостоверения 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.

См. также