Настройка приложения Службы приложений или Функций Azure для входа с использованием поставщика Apple (предварительная версия)

В этой статье показано, как настроить Службу приложений Azure или Функции Azure для использования входа с помощью Apple в качестве поставщика проверки подлинности.

Чтобы выполнить процедуру, описанную в этой статье, необходимо зарегистрироваться в программе Apple Developer. Чтобы зарегистрироваться в программе Apple Developer, перейдите по адресу developer.apple.com/programs/enroll.

Внимание

Включение входа с помощью Apple приведет к отключению управления возможностью "Проверка подлинности и авторизация Службы приложений" с помощью некоторых клиентов, таких как портал Azure, Azure CLI и Azure PowerShell. Эта возможность использует новую поверхность API, которая на время действия предварительной версии еще не учитывается во всех средствах управления.

Создание приложения на портале разработчика Apple

Вам потребуется создать идентификатор приложения и идентификатор службы на портале Apple Developer.

  1. На портале Apple Developer выберите Certificates, Identifiers, & Profiles (Сертификаты, идентификаторы и профили).
  2. На вкладке Identifiers (Идентификаторы) нажмите кнопку (+).
  3. На странице Register a New Identifier (Регистрация нового идентификатора) выберите App IDs (Идентификаторы приложений) и нажмите кнопку Continue (Продолжить). (Идентификаторы приложений включают один или несколько идентификаторов служб.) Registering a new app identifier in the Apple Developer Portal
  4. На странице Register an App ID (Регистрация идентификатора приложения) укажите описание и идентификатор пакета, а затем выберите Sign in with Apple (Вход с помощью Apple) из списка возможностей. Затем выберите Continue (Продолжить). Запишите полученный на этом шаге префикс идентификатора приложения (идентификатор команды). Она понадобится позже. Configuring a new app identifier in the Apple Developer Portal
  5. Проверьте сведения о регистрации приложения и нажмите кнопку Register (Зарегистрировать).
  6. На вкладке Identifiers (Идентификаторы) еще раз нажмите кнопку (+). Creating a new service identifier in the Apple Developer Portal
  7. На странице Register a New Identifier (Регистрация нового идентификатора) выберите Services IDs (Идентификаторы служб) и нажмите кнопку Continue (Продолжить). Registering a new service identifier in the Apple Developer Portal
  8. На странице Register a Services ID (Регистрация идентификатора службы) укажите описание и идентификатор. Описание будет отображено для пользователя на экране предоставления согласия. Идентификатор будет идентификатором клиента, используемым при настройке поставщика Apple в службе приложений. Затем выберите Настроить. Providing a description and an identifier
  9. Во всплывающем окне в поле "Primary App Id" (Основной идентификатор приложения) укажите идентификатор приложения, созданный ранее. Укажите домен приложения в разделе "Domain" (Домен). В качестве URL-адреса возврата укажите URL-адрес <app-url>/.auth/login/apple/callback. Например, https://contoso.azurewebsites.net/.auth/login/apple/callback. Затем выберите Add (Добавить) и Save (Сохранить). Specifying the domain and return URL for the registration
  10. Проверьте сведения о регистрации службы и нажмите кнопку Save (Сохранить).

Создание секрета клиента

Компании Apple требуется, чтобы разработчики приложений создавали и подписывали маркер JWT в качестве значения секрета клиента. Чтобы создать этот секрет, сначала создайте и скачайте закрытый ключ на основе эллиптических кривых на портале Apple Developer. Затем используйте этот ключ, чтобы подписать JWT с помощью определенных полезных данных.

Создание и скачивание закрытого ключа

  1. На вкладке Keys (Ключи) на портале Apple Developer выберите Create a key (Создать ключ) или нажмите кнопку (+).
  2. На странице Register a New Key (Регистрация нового ключа) введите имя ключа, установите флажок Sign in with Apple (Вход с помощью Apple) и выберите Configure (Настроить).
  3. На странице Configure Key (Настройка ключа) свяжите ключ с основным идентификатором приложения, созданным ранее, и выберите Save (Сохранить).
  4. Завершите создание ключа. Подтвердите сведения и выберите Continue (Продолжить). Затем просмотрите информацию и выберите Register (Зарегистрировать).
  5. На странице Download Your Key (скачивание ключа) скачайте ключ. Он будет скачан как файл с расширением .p8 (PKCS#8). Содержимое этого файла будет использоваться для подписания JWT секрета клиента.

Структурирование JWT секрета клиента

Компания Apple требует, чтобы секрет клиента был маркером JWT в кодировке Base64. Декодированный маркер JWT должен содержать полезные данные, структурированные как в следующем примере:

{
  "alg": "ES256",
  "kid": "URKEYID001",
}.{
  "sub": "com.yourcompany.app1",
  "nbf": 1560203207,
  "exp": 1560289607,
  "iss": "ABC123DEFG",
  "aud": "https://appleid.apple.com"
}.[Signature]
  • sub: идентификатор клиента Apple (также идентификатор службы);
  • iss: ваш идентификатор команды Apple Developer;
  • aud: маркер получает компания Apple, поэтому она является аудиторией;
  • exp: не более шести месяцев после nbf.

Версия приведенных выше полезных данных в кодировке Base64 выглядит следующим образом: eyJhbGciOiJFUzI1NiIsImtpZCI6IlVSS0VZSUQwMDEifQ.eyJzdWIiOiJjb20ueW91cmNvbXBhbnkuYXBwMSIsIm5iZiI6MTU2MDIwMzIwNywiZXhwIjoxNTYwMjg5NjA3LCJpc3MiOiJBQkMxMjNERUZHIiwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSJ9.ABSXELWuTbgqfrIUz7bLi6nXvkXAz5O8vt0jB2dSHTQTib1x1DSP4__4UrlKI-pdzNg1sgeocolPNTmDKazO8-BHAZCsdeeTNlgFEzBytIpMKFfVEQbEtGRkam5IeclUK7S9oOva4EK4jV4VmgDrr-LGWWO3TaAxAvy3_ZoKohvFFkVG

Примечание. Компания Apple не принимает JWT секретов клиента с датой окончания срока действия более шести месяцев после даты создания (или nbf). Это означает, что вам нужно будет менять свой секрет клиента, как минимум, каждые шесть месяцев.

Дополнительные сведения о создании и проверке маркеров можно найти в документации для разработчиков Apple.

Подписание JWT секрета клиента

Используйте скачанный ранее файл с расширением .p8, чтобы подписать JWT секрета клиента. Это файл PCKS#8, содержащий закрытый ключ подписывания в формате PEM. Существует множество библиотек, которые могут создавать и подписывать JWT.

В Интернете доступно несколько типов библиотек с открытым кодом для создания и подписания маркеров JWT. Дополнительные сведения о создании маркеров JWT см. в разделе JSON Web Token (JWT). Например, одним из способов создания секрета клиента является импорт пакета NuGet Microsoft.IdentityModel.Tokens и запуск небольшого кода C#, показанного ниже.

using Microsoft.IdentityModel.Tokens;

public static string GetAppleClientSecret(string teamId, string clientId, string keyId, string p8key)
{
    string audience = "https://appleid.apple.com";

    string issuer = teamId;
    string subject = clientId;
    string kid = keyId;

    IList<Claim> claims = new List<Claim> {
        new Claim ("sub", subject)
    };

    CngKey cngKey = CngKey.Import(Convert.FromBase64String(p8key), CngKeyBlobFormat.Pkcs8PrivateBlob);

    SigningCredentials signingCred = new SigningCredentials(
        new ECDsaSecurityKey(new ECDsaCng(cngKey)),
        SecurityAlgorithms.EcdsaSha256
    );

    JwtSecurityToken token = new JwtSecurityToken(
        issuer,
        audience,
        claims,
        DateTime.Now,
        DateTime.Now.AddDays(180),
        signingCred
    );
    token.Header.Add("kid", kid);
    token.Header.Remove("typ");

    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

    return tokenHandler.WriteToken(token);
}
  • teamId: ваш идентификатор группы разработчиков Apple.
  • clientId: идентификатор клиента Apple (также идентификатор службы).
  • p8key: ключ в формате PEM. Его можно получить, открыв файл с расширением .p8 в текстовом редакторе и скопировав все строки между -----BEGIN PRIVATE KEY----- и -----END PRIVATE KEY----- без символов разрыва строки.
  • keyId: идентификатор скачанного ключа.

Этот возвращаемый маркер представляет собой значение секрета клиента, которое будет использоваться для настройки поставщика Apple.

Важно!

Секрет клиента — это важные учетные данные безопасности. Не сообщайте этот секрет никому и не раскрывайте его в клиентском приложении.

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

Добавление сведений о поставщике в приложение

Примечание.

Требуемая конфигурация находится в новом формате API, и в настоящее время она поддерживается только конфигурацией на основе файлов (предварительная версия). При использовании такого файла необходимо выполнить приведенные ниже действия.

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

  1. В объекте identityProviders добавьте объект apple, если он еще не существует.

  2. Назначьте объект этому ключу, поместив в него объект registration и при необходимости объект login:

    "apple" : {
       "registration" : {
            "clientId": "<client ID>",
            "clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET" 
        },
       "login": {
             "scopes": []
       }
    }
    

    a. В объекте registration задайте для clientId идентификатор клиента, который вы получили.

    b. В объекте registration задайте для clientSecretSettingName имя параметра приложения, в котором хранится секрет клиента.

    c. В объекте login можно задать массив scopes, чтобы добавить список областей, используемых при проверке подлинности в Apple, например name и email. Если области настроены, они будут явно запрошены на экране предоставления согласия при первом входе пользователей в систему.

Завершив конфигурацию, вы можете использовать поставщик Apple для проверки подлинности в приложении.

Полная конфигурация может выглядеть, как в следующем примере (где параметр APPLE_GENERATED_CLIENT_SECRET указывает на параметр приложения, содержащий созданный маркер JWT):

{
    "platform": {
        "enabled": true
    },
    "globalValidation": {
        "redirectToProvider": "apple",
        "unauthenticatedClientAction": "RedirectToLoginPage"
    },
    "identityProviders": {
        "apple": {
            "registration": {
                "clientId": "com.contoso.example.client",
                "clientSecretSettingName": "APPLE_GENERATED_CLIENT_SECRET"
            },
            "login": {
                "scopes": []
            }
        }
    },
    "login": {
        "tokenStore": {
            "enabled": true
        }
    }     
}

Дальнейшие действия