Бөлісу құралы:


Смена ключей подписывания на платформе удостоверений Майкрософт

В этой статье описывается, что необходимо знать об открытых ключах, используемых платформой удостоверений Майкрософт для подписывания маркеров безопасности. Важно отметить, что эти ключи переворачены периодически и, в чрезвычайной ситуации, могут быть переворачены немедленно. Все приложения, использующие платформу удостоверений Майкрософт, должны иметь возможность программно управлять процессом смены ключей. Вы узнаете, как работают ключи, как оценить влияние переката в приложение и как обновить приложение или установить периодический процесс переключения ключей вручную при необходимости.

Общие сведения о ключах подписывания на платформе удостоверений Майкрософт

Платформа удостоверений Майкрософт использует шифрование с открытым ключом на основе отраслевых стандартов, чтобы устанавливать доверительные отношения с приложениями, использующими эту платформу. В частности, это происходит следующим образом. Платформа удостоверений Майкрософт использует ключ подписывания, состоящий из пары открытого и закрытого ключей. Когда пользователь входит в приложение, использующее платформу удостоверений Майкрософт для проверки подлинности, платформа удостоверений Майкрософт создает маркер безопасности, содержащий сведения об этом пользователе. Этот маркер подписан платформа удостоверений Майкрософт с помощью закрытого ключа перед отправкой в приложение. Чтобы убедиться, что маркер действителен и получен от платформы удостоверений Майкрософт, приложение должно проверить его подпись с помощью открытого ключа. Этот ключ предоставляется платформой удостоверений Майкрософт и содержится в документе обнаружения OpenID Connect или документе метаданных федерации SAML/WS-Fed арендатора.

В целях безопасности ключи подписывания платформы удостоверений Майкрософт периодически сменяются, а в случае чрезвычайной ситуации могут быть изменены немедленно. Между этими свертками ключей не задано или гарантированное время. Любое приложение, которое интегрируется с платформа удостоверений Майкрософт, должно быть готово к обработке события отката ключей независимо от того, насколько часто это может произойти. Если приложение не обрабатывает внезапные обновления и пытается использовать истекший срок действия ключа для проверки подписи маркера, приложение неправильно отклоняет маркер. Рекомендуется проверять наличие обновлений каждые 24 часа, а также применять регулируемые (не чаще, чем раз в 5 минут) немедленные обновления документа ключей, если обнаружен маркер, который не проходит проверку с ключами, хранящимися в кэше приложения.

В документе обнаружения OpenID Подключение и документе метаданных федерации всегда доступно несколько допустимых ключей. Следует подготовить приложение к использованию любого из ключей, указанных в документе, так как один ключ может быть скоро сменен, другой может оказаться его заменой и т. д. Число имеющихся ключей может меняться со временем в зависимости от внутренней архитектуры платформы удостоверений Майкрософт, так как мы добавляем поддержку новых платформ, новых облаков и новых протоколов проверки подлинности. Ни порядок ключей в ответе JSON, ни порядок, в котором они были предоставлены, не должен иметь значения для приложения.

Приложения, поддерживающие только один ключ подписывания или требующие ручного обновления ключей подписывания, по своей природе менее безопасны и менее надежны. Они должны быть обновлены, чтобы использовать стандартные библиотеки , чтобы гарантировать, что они всегда используют актуальные ключи подписывания, среди других рекомендаций.

Как оценить степень влияния смены ключей на приложение

Обработка смены ключей в приложении зависит от нескольких переменных, например от типа приложения или используемых протокола идентификации и библиотеки. В приведенных ниже разделах рассматривается, влияет ли смена ключей на самые распространенные типы приложений, а также содержатся рекомендации по обновлению приложения для поддержки автоматической смены ключей и обновлении ключей вручную.

Это руководство не применимо к:

  • Приложения, добавленные из коллекции приложений Microsoft Entra (включая custom), имеют отдельные рекомендации по ключам подписывания. Дополнительные сведения.
  • локальным приложениям, опубликованным через прокси приложения, так как им не требуются ключи подписывания.

Собственные клиентские приложения, осуществляющие доступ к ресурсам

Приложения, которые получают доступ только к ресурсам (например, Microsoft Graph, KeyVault, API Outlook и другие API Майкрософт), получают маркер и передают его владельцу ресурса. Учитывая, что они не защищают какие-либо ресурсы, они не проверяют маркер и поэтому не должны убедиться, что он правильно подписан.

Собственные клиентские приложения, будь то классические или мобильные, попадают в эту категорию. Поэтому смена ключей не влияет на этот тип приложений.

Веб-приложения и интерфейсы API, осуществляющие доступ к ресурсам

Приложения, которые обращаются только к ресурсам (например, Microsoft Graph, KeyVault, API Outlook и другим API Майкрософт), получают маркер и передают его владельцу ресурса. Учитывая, что они не защищают какие-либо ресурсы, они не проверяют маркер и поэтому не должны убедиться, что он правильно подписан.

Веб-приложения и интерфейсы API, использующие для запроса маркеров поток только для приложений (учетные данные или сертификат клиента), попадают в эту категорию. Поэтому смена ключей не влияет на этот тип приложений.

Защищающие ресурсы веб-приложения и интерфейсы API, созданные с помощью служб приложений Azure

В функциях проверки подлинности и авторизации (EasyAuth) служб приложений Azure уже предусмотрена логика для обработки автоматической смены ключей.

Веб-приложения или API-интерфейсы, защищающие ресурсы с помощью по промежуточного слоя OWIN OpenID ASP.NET Подключение, WS-Fed или WindowsAzureActiveDirectoryBearerAuthentication

Если приложение использует ASP.NET Подключение OWIN OpenID Подключение, WS-Fed или ПО промежуточного слоя WindowsAzureActiveDirectoryBearerAuthentication, она уже имеет необходимую логику для автоматического переключения ключей.

Чтобы проверить это, нужно поискать один из следующих фрагментов кода в файле Startup.cs или Startup.Auth.cs приложения.

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        // ...
    });
app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        // ...
    });
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
    new WindowsAzureActiveDirectoryBearerAuthenticationOptions
    {
        // ...
    });

Веб-приложения и интерфейсы API, защищающие ресурсы с использованием ПО промежуточного слоя для аутентификации на основе токена носителя JWT или OpenID Connect .NET Core

Если приложение использует ASP.NET OWIN OpenID Подключение или ПО промежуточного слоя JwtBearerAuthentication, она уже имеет необходимую логику для автоматического переключения ключей.

Чтобы проверить это, нужно поискать один из следующих фрагментов кода в файле Startup.cs или Startup.Auth.cs приложения.

app.UseOpenIdConnectAuthentication(
     new OpenIdConnectAuthenticationOptions
     {
         // ...
     });
app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    {
     // ...
     });

Веб-приложения или API-интерфейсы, защищающие ресурсы с помощью модуля Node.js passport-azure-ad

Если в приложении используется модуль Node.js passport-ad, в нем уже предусмотрена логика для обработки автоматической смены ключей.

Это можно проверить, выполнив поиск следующего фрагмента кода в файле app.js приложения.

var OIDCStrategy = require('passport-azure-ad').OIDCStrategy;

passport.use(new OIDCStrategy({
    //...
));

Защищающие ресурсы веб-приложения и интерфейсы API, созданные в Visual Studio 2015 или более поздней версии

Если приложение создано в Visual Studio 2015 или более поздней версии с использованием шаблона веб-приложения и в меню Изменить способ проверки подлинности выбран пункт Рабочие или учебные учетные записи, в приложении уже есть необходимая логика для обработки автоматической смены ключей. Эта логика, внедренная в ПО промежуточного слоя OWIN OpenID Подключение, извлекает и кэширует ключи из документа обнаружения OpenID Подключение и периодически обновляет их.

Если проверка подлинности добавлена в решение вручную, в приложении может отсутствовать необходимая логика смены ключей. Вы можете написать его самостоятельно или выполнить действия, описанные в веб-приложениях или API, используя любые другие библиотеки или вручную реализуя любой из поддерживаемых протоколов.

Защищающие ресурсы веб-приложения, созданные в Visual Studio 2013

Если приложение создано в Visual Studio 2013 с использованием шаблона веб-приложения и в меню Изменить способ проверки подлинности выбран пункт Учетные записи организации, в приложении уже есть необходимая логика для обработки автоматической смены ключей. Логика хранит уникальный идентификатор организации и сведения о ключе подписывания в двух таблицах базы данных, связанных с проектом. Строку подключения для базы данных можно найти в файле Web.config проекта.

Если проверка подлинности добавлена в решение вручную, в приложении может отсутствовать необходимая логика смены ключей. Вам потребуется написать его самостоятельно или выполнить действия, описанные в веб-приложениях или API, используя любые другие библиотеки или вручную реализуя любой из поддерживаемых протоколов.

Следующие шаги помогут убедиться, что логика работает правильно в приложении.

  1. В Visual Studio 2013 откройте решение и перейдите на вкладку "Сервер Обозреватель" в правом окне.
  2. Разверните узлы Подключения данных, DefaultConnection, а затем — Таблицы. Найдите таблицу IssuingAuthorityKeys , щелкните ее правой кнопкой мыши и выберите команду "Показать данные таблицы".
  3. В таблице IssuingAuthorityKeys будет по крайней мере одна строка, соответствующая значению отпечатка для ключа. Удалите все строки в таблице.
  4. Щелкните правой кнопкой мыши таблицу "Клиенты" , а затем выберите " Показать данные таблицы".
  5. В таблице Клиенты будет по крайней мере одна строка, соответствующая уникальному идентификатору клиента каталога. Удалите все строки в таблице. Если вы не удаляете строки в таблице "Клиенты " и в таблице "ВыдающийAuthorityKeys ", вы получите ошибку во время выполнения.
  6. Выполните сборку приложения и запустите его. Войдя в учетную запись, можно остановить работу приложения.
  7. Вернитесь в обозреватель сервера и просмотрите значения в таблицах IssuingAuthorityKeys и Tenants. Как можно заметить, в них автоматически добавлены соответствующие сведения из документа метаданных федерации.

Защищающие ресурсы веб-API, созданные в Visual Studio 2013

Если приложение веб-API создано в Visual Studio 2013 с использованием шаблона веб-API и в меню Изменить способ проверки подлинности выбран пункт Учетные записи организации, в нем уже есть необходимая логика.

Если проверка подлинности настроена вручную, следуйте указаниям ниже, чтобы узнать, как настроить веб-API для автоматического обновления сведений о ключах.

В следующем фрагменте кода показано, как получить последние ключи из документа метаданных федерации, а затем использовать обработчик маркера JWT для проверки маркера. В фрагменте кода предполагается, что вы будете использовать собственный механизм кэширования для сохранения ключа для проверки будущих маркеров из платформа удостоверений Майкрософт, будь то в базе данных, файле конфигурации или в другом месте.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IdentityModel.Tokens;
using System.Configuration;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.IdentityModel.Metadata;
using System.ServiceModel.Security;
using System.Threading;

namespace JWTValidation
{
    public class JWTValidator
    {
        private string MetadataAddress = "[Your Federation Metadata document address goes here]";

        // Validates the JWT Token that's part of the Authorization header in an HTTP request.
        public void ValidateJwtToken(string token)
        {
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler()
            {
                // Do not disable for production code
                CertificateValidator = X509CertificateValidator.None
            };

            TokenValidationParameters validationParams = new TokenValidationParameters()
            {
                AllowedAudience = "[Your App ID URI goes here]",
                ValidIssuer = "[The issuer for the token goes here, such as https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/]",
                SigningTokens = GetSigningCertificates(MetadataAddress)

                // Cache the signing tokens by your desired mechanism
            };

            Thread.CurrentPrincipal = tokenHandler.ValidateToken(token, validationParams);
        }

        // Returns a list of certificates from the specified metadata document.
        public List<X509SecurityToken> GetSigningCertificates(string metadataAddress)
        {
            List<X509SecurityToken> tokens = new List<X509SecurityToken>();

            if (metadataAddress == null)
            {
                throw new ArgumentNullException(metadataAddress);
            }

            using (XmlReader metadataReader = XmlReader.Create(metadataAddress))
            {
                MetadataSerializer serializer = new MetadataSerializer()
                {
                    // Do not disable for production code
                    CertificateValidationMode = X509CertificateValidationMode.None
                };

                EntityDescriptor metadata = serializer.ReadMetadata(metadataReader) as EntityDescriptor;

                if (metadata != null)
                {
                    SecurityTokenServiceDescriptor stsd = metadata.RoleDescriptors.OfType<SecurityTokenServiceDescriptor>().First();

                    if (stsd != null)
                    {
                        IEnumerable<X509RawDataKeyIdentifierClause> x509DataClauses = stsd.Keys.Where(key => key.KeyInfo != null && (key.Use == KeyType.Signing || key.Use == KeyType.Unspecified)).
                                                             Select(key => key.KeyInfo.OfType<X509RawDataKeyIdentifierClause>().First());

                        tokens.AddRange(x509DataClauses.Select(token => new X509SecurityToken(new X509Certificate2(token.GetX509RawData()))));
                    }
                    else
                    {
                        throw new InvalidOperationException("There is no RoleDescriptor of type SecurityTokenServiceType in the metadata");
                    }
                }
                else
                {
                    throw new Exception("Invalid Federation Metadata document");
                }
            }
            return tokens;
        }
    }
}

Защищающие ресурсы веб-приложения, созданные в Visual Studio 2012

Если приложение создано в Visual Studio 2012, вероятно, оно настроено с помощью средства Identity and Access Tool. Кроме того, возможно, используется проверка реестра имен поставщиков. VINR отвечает за обслуживание сведений о доверенных поставщиках удостоверений (платформа удостоверений Майкрософт) и ключах, используемых для проверки маркеров, которые выдали эти поставщики. VINR также упрощает автоматическое обновление сведений о ключах, хранящихся в файле Web.config. Для этого скачивается последний документ метаданных федерации, связанный с каталогом, проверяется,не устарела ли конфигурация по сравнению с этим документом, и приложение обновляется для использования нового ключа при необходимости.

Если приложение создано с использованием любого из примеров кода или документации с пошаговыми инструкциями, предоставленных корпорацией Майкрософт, логика смены ключей уже добавлена в проект. Вы заметите, что код ниже уже есть в проекте. Если в приложении нет этой логики, выполните следующие шаги, чтобы добавить ее и убедиться в правильности ее работы.

  1. В обозревателе решений добавьте ссылку на сборку System.IdentityModel для соответствующего проекта.
  2. Откройте файл Global.asax.cs и добавьте следующие директивы using:
    using System.Configuration;
    using System.IdentityModel.Tokens;
    
  3. Добавьте следующий метод в файл Global.asax.cs :
    protected void RefreshValidationSettings()
    {
     string configPath = AppDomain.CurrentDomain.BaseDirectory + "\\" + "Web.config";
     string metadataAddress =
                   ConfigurationManager.AppSettings["ida:FederationMetadataLocation"];
     ValidatingIssuerNameRegistry.WriteToConfig(metadataAddress, configPath);
    }
    
  4. Вызов метода RefreshValidation Параметры() в методе Application_Start() в Global.asax.cs, как показано ниже.
    protected void Application_Start()
    {
     AreaRegistration.RegisterAllAreas();
     ...
     RefreshValidationSettings();
    }
    

После выполнения этих шагов файл Web.config приложения обновится с использованием последних сведений документа метаданных федерации, в том числе последних ключей. Это обновление будет выполняться при каждом перезапуске пула приложений в IIS. По умолчанию в IIS настроен перезапуск приложений через каждые 29 часов.

Выполните следующие шаги, чтобы убедиться, что логика смены ключей работает должным образом.

  1. Убедившись, что приложение использует приведенный выше код, откройте файл web.config и перейдите к блоку <issuerNameRegistry>, специально ищете следующие несколько строк:
    <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
         <authority name="https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/">
           <keys>
             <add thumbprint="AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" />
           </keys>
    
  2. В параметре <add thumbprint=""> измените значение отпечатка, заменив любой из знаков другим знаком. Сохраните файл Web.config .
  3. Выполните сборку приложения и запустите его. Если у вас получилось войти, приложение успешно обновляет ключ, скачивая необходимые данные из документа метаданных федерации каталога. Если у вас возникли проблемы с входом, убедитесь, что изменения в приложении исправлены, прочитайте статью "Добавление входа в веб-приложение с помощью платформа удостоверений Майкрософт" или скачивание и проверка следующего примера кода: многотенантное облачное приложение для идентификатора Microsoft Entra.

Веб-приложения и интерфейсы API, защищающие ресурсы с помощью других библиотек или ручного внедрения поддерживаемых протоколов

Если используется другая библиотека или вручную внедрены поддерживаемые протоколы, их необходимо проверить, чтобы убедиться, что ключ извлекается из документа обнаружения OpenID Connect или документа метаданных федерации. Для этого необходимо проверить в коде приложения или коде библиотеки наличие вызовов документа обнаружения OpenID Connect или документа метаданных федерации.

Если ключ хранится в другом месте или включен в код приложения, его можно вручную извлечь и обновить, выполнив смену ключа вручную согласно инструкциям, приведенным в конце этого руководства. Настоятельно рекомендуем настроить поддержку автоматической смены ключей в приложении, используя методы, описанные в этой статье, чтобы в будущем избежать нарушений работы и дополнительных затрат в том случае, если на платформе удостоверений Майкрософт будет повышена частота смены или произойдет внештатная аварийная смена ключей.

Тестирование приложения для оценки степени влияния

Вы можете проверить, поддерживает ли приложение автоматическую смену ключей, используя следующие скрипты PowerShell.

Чтобы проверка и обновить ключи подписи с помощью PowerShell, вам потребуется модуль MSIdentityTools PowerShell.

  1. Установите модуль PowerShell MSIdentityTools:

    Install-Module -Name MSIdentityTools
    
  2. Войдите в систему, используя команду Connect-MgGraph с учетной записью администратора, чтобы предоставить согласие на требуемые области:

     Connect-MgGraph -Scope "Application.ReadWrite.All"
    
  3. Получите список доступных отпечатков ключей подписывания:

    Get-MsIdSigningKeyThumbprint
    
  4. Выберите любой из отпечатков ключей и настройте идентификатор Microsoft Entra для использования этого ключа с приложением (получите идентификатор приложения из Центра администрирования Microsoft Entra):

    Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -KeyThumbprint <Thumbprint>
    
  5. Протестируйте работу веб-приложение, выполнив вход для получения нового маркера. Обновление ключа выполняется мгновенно, но для его создания необходимо создать новый сеанс в браузере (например, использовать режим "InPrivate" в Internet Explorer, "Инкогнито" в Chrome или "Частный" в Firefox).

  6. Для каждого из возвращенных отпечатков ключей подписывания запустите командлет Update-MsIdApplicationSigningKeyThumbprint и проверьте процесс входа в веб-приложение.

  7. Если веб-приложение правильно выполняет вход, значит оно поддерживает автоматическую смену ключей. В противном случае нужно изменить приложение, чтобы оно поддерживало смену ключей вручную. Дополнительные сведения по этой теме можно получить в разделе Организация процесса смены ключей вручную.

  8. Выполните следующий скрипт, чтобы вернуться к нормальному поведению:

    Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -Default
    

Как сменить ключи вручную, если приложение не поддерживает автоматическую смену ключей

Если приложение не поддерживает автоматическую смену ключей, необходимо создать процесс, который будет периодически отслеживать ключи подписывания платформы удостоверений Майкрософт и выполнять смену ключей вручную по мере необходимости.

Чтобы проверка и обновить ключи подписывания с помощью PowerShell, потребуется MSIdentityTools модуль PowerShell.

  1. MSIdentityTools Установите модуль PowerShell:

    Install-Module -Name MSIdentityTools
    
  2. Получите последний ключ подписи (получите идентификатор клиента из Центра администрирования Microsoft Entra):

    Get-MsIdSigningKeyThumbprint -Tenant <tenandId> -Latest
    
  3. Сравните этот ключ с тем ключом, который сейчас включен в код приложения или настроен для использования.

  4. Если последний ключ отличается от используемого приложением ключа, скачайте последний ключ подписывания:

    Get-MsIdSigningKeyThumbprint -Latest -DownloadPath <DownloadFolderPath>
    
  5. Обновите код или конфигурацию приложения, чтобы оно использовало новый ключ.

  6. Настройте идентификатор Microsoft Entra, чтобы использовать этот последний ключ с приложением (получите идентификатор приложения из Центра администрирования Microsoft Entra):

    Get-MsIdSigningKeyThumbprint -Latest | Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId>
    
  7. Протестируйте работу веб-приложение, выполнив вход для получения нового маркера. Обновление ключа выполняется мгновенно, но для его создания необходимо создать новый сеанс в браузере (например, использовать режим "InPrivate" в Internet Explorer, "Инкогнито" в Chrome или "Частный" в Firefox).

  8. Если возникнут любые проблемы, вернитесь к предыдущему ключу, который вы использовали ранее, и обратитесь в службу поддержки Azure:

    Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -KeyThumbprint <PreviousKeyThumbprint>
    
  9. Завершив настройку приложения для поддержки обновления ключей вручную, переключитесь на нормальный режим работы:

    Update-MsIdApplicationSigningKeyThumbprint -ApplicationId <ApplicationId> -Default