Настройка потока учетных данных пароля владельца ресурса в Azure Active Directory B2C
Для начала с помощью селектора Choose a policy type (Выбрать тип политики) выберите тип пользовательской политики. Azure Active Directory B2C предлагает два метода определения способа взаимодействия пользователей с вашими приложениями: с помощью предопределенных потоков пользователей или полностью настраиваемых пользовательских политик. Действия, которые необходимо выполнить, отличаются для каждого метода.
В Azure Active Directory B2C (Azure AD B2C) поток учетных данных пароля владельца ресурса (ROPC) — это процесс стандартной аутентификации OAuth. В этом потоке приложение, также известное как проверяющая сторона, обменивает действительные учетные данные на маркеры проверки подлинности. Учетные данные включают идентификатор пользователя и пароль. Возвращается маркер идентификации, маркер доступа и маркер обновления.
Предупреждение
Рекомендуется не использовать поток ROPC. В большинстве случаев доступны и рекомендуются более безопасные альтернативы. Этот поток требует очень высокой степени доверия к приложению и несет риски, которые не присутствуют в других потоках. Этот поток следует использовать только при невозможности использовать другие, более безопасные потоки.
Примечания к потоку ROPC
В Azure Active Directory B2C (Azure AD B2C) поддерживаются следующие параметры:
- Собственный клиент. Взаимодействие с пользователем во время аутентификации происходит, когда код выполняется на устройстве на стороне пользователя. Устройство может быть мобильным приложением, которое выполняется в собственной операционной системе, например Android и iOS.
- Поток общедоступного клиента. При вызове API отправляются только учетные данные, полученные приложением. Учетные данные приложения не отправляются.
- Добавление новых утверждений. Содержимое токена идентификатора можно изменить для добавления новых утверждений.
Следующие потоки не поддерживаются.
- Сервер-сервер. Системе защиты идентификации требуются надежные IP-адреса, полученные от вызывающего объекта (собственного клиента) в рамках взаимодействия. При вызове API на стороне сервера используется только IP-адрес сервера. При превышении динамического порога неудачных проверок подлинности система защиты идентификации может рассматривать повторяющийся IP-адрес как адрес злоумышленника.
- Конфиденциальный поток клиента: проверяется идентификатор клиента приложения, но секрет приложения не проверяется.
При использовании потока ROPC учитывайте следующее:
- ROPC не работает, когда возникает прерывание потока проверки подлинности, требующего взаимодействия с пользователем. Например, если срок действия пароля истек или его необходимо изменить, требуется многофакторная проверка подлинности, или когда необходимо собрать дополнительные сведения во время входа (например, согласие пользователя).
- ROPC поддерживает только локальные учетные записи. Пользователи не могут выполнять вход с помощью федеративных поставщиков удостоверений, таких как Microsoft, Google +, Twitter, AD-FS или Facebook.
- Управление сеансами, включая сохранение входа в систему (KMSI), неприменимо.
Регистрация приложения
Чтобы зарегистрировать приложение в клиенте Azure AD B2C, можно использовать новый унифицированный интерфейс Регистрации приложений или устаревший интерфейс приложений (прежняя версия). См. дополнительные сведения о новом интерфейсе.
- Войдите на портал Azure.
- Убедитесь, что вы используете каталог, содержащий клиент Azure AD B2C:
- На панели инструментов портала выберите значок Каталоги и подписки.
- В настройках портала на странице Каталоги и подписки найдите свой каталог Azure AD B2C в списке Имя каталога и выберите Переключить.
- На портале Azure найдите и выберите Azure AD B2C.
- Щелкните Регистрация приложений и выберите Новая регистрация.
- Введите имя приложения. Например, ROPC_Auth_app.
- Не меняя остальные значения, нажмите кнопку Зарегистрировать.
- Запишите значение параметра Идентификатор приложения (клиент). Оно вам потребуется в дальнейшем.
- В разделе Управление выберите Проверка подлинности.
- Выберите Попробовать новый пользовательский интерфейс (если этот параметр показан).
- В разделе Дополнительные параметры и Разрешать потоки общедоступных клиентов, установите переключатель Да, чтобы приложение считалось общедоступным клиентом. Этот параметр требуется для потока ROPC.
- Выберите Сохранить.
- В левом меню выберите Манифест, чтобы открыть редактор манифестов.
- Задайте для атрибута oauth2AllowImplicitFlow значение true:
"oauth2AllowImplicitFlow": true,
- Выберите Сохранить.
Создание потока пользователя владельца ресурса
- Войдите на портал Azure с правами глобального администратора арендатора Azure AD B2C.
- Если у вас есть доступ к нескольким клиентам, выберите значок Параметры в верхнем меню, чтобы переключиться на клиент Azure AD B2C из меню каталогов и подписок.
- В портале Azure найдите и выберите Azure AD B2C.
- Выберите Потоки пользователей и Создать поток пользователя.
- Выберите Вход с использованием учетных данных владельца ресурса (ROPC).
- В разделе Версия обязательно установите флажок Предварительная версия и нажмите кнопку Создать.
- Укажите имя потока пользователя, например ROPC_Auth.
- В разделе Утверждения приложения выберите элемент Показать еще.
- Выберите утверждения приложения, которые необходимы для вашего приложения, такие как "Отображаемое имя", "Адрес электронной почты" и "Поставщик удостоверений".
- Щелкните ОК, а затем выберите Создать.
Необходимые условия
Ознакомьтесь со статьей Начало работы с настраиваемыми политиками в Azure Active Directory B2C, чтобы узнать о базовом пакете настраиваемых политик, если еще не сделали этого.
Создание политики владельца ресурса
Откройте файл TrustFrameworkExtensions.xml.
Если он еще не существует, добавьте элемент ClaimsSchema и его дочерние элементы в качестве первого элемента в элементе BuildingBlocks.
<ClaimsSchema> <ClaimType Id="logonIdentifier"> <DisplayName>User name or email address that the user can use to sign in</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="resource"> <DisplayName>The resource parameter passes to the ROPC endpoint</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="refreshTokenIssuedOnDateTime"> <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="refreshTokensValidFromDateTime"> <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName> <DataType>string</DataType> </ClaimType> </ClaimsSchema>
После ClaimsSchema добавьте элемент ClaimsTransformations и его дочерние элементы в элемент BuildingBlocks.
<ClaimsTransformations> <ClaimsTransformation Id="CreateSubjectClaimFromObjectID" TransformationMethod="CreateStringClaim"> <InputParameters> <InputParameter Id="value" DataType="string" Value="Not supported currently. Use oid claim." /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="sub" TransformationClaimType="createdClaim" /> </OutputClaims> </ClaimsTransformation> <ClaimsTransformation Id="AssertRefreshTokenIssuedLaterThanValidFromDate" TransformationMethod="AssertDateTimeIsGreaterThan"> <InputClaims> <InputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" TransformationClaimType="leftOperand" /> <InputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" TransformationClaimType="rightOperand" /> </InputClaims> <InputParameters> <InputParameter Id="AssertIfEqualTo" DataType="boolean" Value="false" /> <InputParameter Id="AssertIfRightOperandIsNotPresent" DataType="boolean" Value="true" /> </InputParameters> </ClaimsTransformation> </ClaimsTransformations>
Найдите элемент ClaimsProvider, у которого параметр DisplayName имеет значение
Local Account SignIn
, и добавьте следующий технической профиль.<TechnicalProfile Id="ResourceOwnerPasswordCredentials-OAUTH2"> <DisplayName>Local Account SignIn</DisplayName> <Protocol Name="OpenIdConnect" /> <Metadata> <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item> <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item> <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item> <Item Key="DiscoverMetadataByTokenIssuer">true</Item> <Item Key="ValidTokenIssuerPrefixes">https://sts.windows.net/</Item> <Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item> <Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item> <Item Key="response_types">id_token</Item> <Item Key="response_mode">query</Item> <Item Key="scope">email openid</Item> <Item Key="grant_type">password</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="logonIdentifier" PartnerClaimType="username" Required="true" DefaultValue="{OIDC:Username}"/> <InputClaim ClaimTypeReferenceId="password" Required="true" DefaultValue="{OIDC:Password}" /> <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" /> <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" /> <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" /> <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" /> <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" /> <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" /> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" /> </OutputClaimsTransformations> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
Замените параметр DefaultValue для client_id идентификатором приложения ProxyIdentityExperienceFramework, созданного в учебнике о предварительных требованиях. Затем замените DefaultValue для resource_id идентификатором приложения IdentityExperienceFramework, созданного при работе с учебником о предварительных требованиях.
Добавьте следующие элементы ClaimsProvider с техническими профилями в элемент ClaimsProviders.
<ClaimsProvider> <DisplayName>Azure Active Directory</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="AAD-UserReadUsingObjectId-CheckRefreshTokenDate"> <Metadata> <Item Key="Operation">Read</Item> <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="objectId" Required="true" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="objectId" /> <OutputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" /> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="AssertRefreshTokenIssuedLaterThanValidFromDate" /> <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" /> </OutputClaimsTransformations> <IncludeTechnicalProfile ReferenceId="AAD-Common" /> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider> <ClaimsProvider> <DisplayName>Session Management</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="SM-RefreshTokenReadAndSetup"> <DisplayName>Trustframework Policy Engine Refresh Token Setup Technical Profile</DisplayName> <Protocol Name="None" /> <OutputClaims> <OutputClaim ClaimTypeReferenceId="objectId" /> <OutputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" /> </OutputClaims> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider> <ClaimsProvider> <DisplayName>Token Issuer</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="JwtIssuer"> <Metadata> <!-- Point to the redeem refresh token user journey--> <Item Key="RefreshTokenUserJourneyId">ResourceOwnerPasswordCredentials-RedeemRefreshToken</Item> </Metadata> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider>
Добавьте элемент UserJourneys и его дочерние элементы в элемент TrustFrameworkPolicy.
<UserJourney Id="ResourceOwnerPasswordCredentials"> <PreserveOriginalAssertion>false</PreserveOriginalAssertion> <OrchestrationSteps> <OrchestrationStep Order="1" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="ResourceOwnerFlow" TechnicalProfileReferenceId="ResourceOwnerPasswordCredentials-OAUTH2" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="2" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> </OrchestrationSteps> </UserJourney> <UserJourney Id="ResourceOwnerPasswordCredentials-RedeemRefreshToken"> <PreserveOriginalAssertion>false</PreserveOriginalAssertion> <OrchestrationSteps> <OrchestrationStep Order="1" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="RefreshTokenSetupExchange" TechnicalProfileReferenceId="SM-RefreshTokenReadAndSetup" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="2" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="CheckRefreshTokenDateFromAadExchange" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId-CheckRefreshTokenDate" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> </OrchestrationSteps> </UserJourney>
На странице Пользовательские политики в клиенте Azure AD B2C выберите Отправить политику.
Включите функцию Перезаписать политику, если она уже существует, а затем найдите и выберите файл TrustFrameworkExtensions.xml.
Выберите Отправить.
Создание файла проверяющей стороны
Теперь обновите файл проверяющей стороны, который активирует созданный путь взаимодействия пользователя.
Создайте копию файла SignUpOrSignIn.xml в рабочем каталоге и переименуйте его в ROPC_Auth.xml.
Откройте новый файл и обновите значение атрибута PolicyId для TrustFrameworkPolicy, указав уникальное значение. Идентификатор политики — это имя вашей политики. Например, B2C_1A_ROPC_Auth.
Измените значение атрибута ReferenceId в DefaultUserJourney на
ResourceOwnerPasswordCredentials
.Измените элемент OutputClaims, чтобы он содержал только следующие утверждения.
<OutputClaim ClaimTypeReferenceId="sub" /> <OutputClaim ClaimTypeReferenceId="objectId" /> <OutputClaim ClaimTypeReferenceId="displayName" DefaultValue="" /> <OutputClaim ClaimTypeReferenceId="givenName" DefaultValue="" /> <OutputClaim ClaimTypeReferenceId="surname" DefaultValue="" />
На странице Пользовательские политики в клиенте Azure AD B2C выберите Отправить политику.
Включите функцию Перезаписать политику, если она уже существует, а затем найдите и выберите файл ROPC_Auth.xml.
Выберите Отправить.
Тестирование потока ROPC
С помощью предпочитаемого приложения по разработке API создайте вызов API и просмотрите ответ, чтобы отладить политику. Создайте вызов, как в этом примере, со следующими сведениями в качестве текста запроса POST.
https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token
- Замените
<tenant-name>
именем вашего клиента Azure AD B2C. - Замените
B2C_1A_ROPC_Auth
полным именем политики учетных данных пароля владельца ресурса.
Ключ | Значение |
---|---|
username | user-account |
password | password1 |
grant_type | password |
область | openid application-id offline_access |
client_id | application-id |
response_type | token id_token |
- Замените
user-account
на имя учетной записи пользователя в клиенте. - Замените
password1
паролем к учетной записи пользователя. - Замените
application-id
на идентификатор приложения из регистрации ROPC_Auth_app. - Offline_access является необязательным, если вы хотите получить токен обновления.
Фактический запрос POST выглядит так.
POST /<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.com
Content-Type: application/x-www-form-urlencoded
username=contosouser.outlook.com.ws&password=Passxword1&grant_type=password&scope=openid+bef22d56-552f-4a5b-b90a-1988a7d634ce+offline_access&client_id=bef22d56-552f-4a5b-b90a-1988a7d634ce&response_type=token+id_token
Успешный ответ с автономным доступом выглядит так:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki...",
"token_type": "Bearer",
"expires_in": "3600",
"refresh_token": "eyJraWQiOiJacW9pQlp2TW5pYVc2MUY0TnlfR3REVk1EVFBLbUJLb0FUcWQ1ZWFja1hBIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6Ij...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki..."
}
Погашение токена обновления
Создайте вызов POST, аналогичный приведенному здесь. Используйте приведенные в таблице ниже сведения в качестве текста запроса.
https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token
- Замените
<tenant-name>
именем вашего клиента Azure AD B2C. - Замените
B2C_1A_ROPC_Auth
полным именем политики учетных данных пароля владельца ресурса.
Ключ | Значение |
---|---|
grant_type | refresh_token |
response_type | id_token |
client_id | application-id |
resource | application-id |
refresh_token | refresh-token |
- Замените
application-id
на идентификатор приложения из регистрации ROPC_Auth_app. - Замените
refresh-token
на refresh_token, который был отправлен в предыдущем ответе.
Успешный ответ выглядит примерно так:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhT...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQn...",
"token_type": "Bearer",
"not_before": 1533672990,
"expires_in": 3600,
"expires_on": 1533676590,
"resource": "bef2222d56-552f-4a5b-b90a-1988a7d634c3",
"id_token_expires_in": 3600,
"profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiI1MTZmYzA2NS1mZjM2LTRiOTMtYWE1YS1kNmVlZGE3Y2JhYzgiLCJzdWIiOm51bGwsIm5hbWUiOiJEYXZpZE11IiwicHJlZmVycmVkX3VzZXJuYW1lIjpudWxsLCJpZHAiOiJMb2NhbEFjY291bnQifQ",
"refresh_token": "eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAi...",
"refresh_token_expires_in": 1209600
}
Устранение неполадок
Предоставленное приложение не настроено для разрешения неявного потока OAuth
- Симптом . Вы запускаете поток ROPC и получаете следующее сообщение: AADB2C90057: предоставленное приложение не настроено для разрешения неявного потока OAuth.
- Возможные причины. Неявный поток не допускается для приложения.
- Решение. При создании регистрации приложения в Azure AD B2C вам нужно вручную изменить манифест приложения и задать для свойства
oauth2AllowImplicitFlow
значениеtrue
. После настройки свойстваoauth2AllowImplicitFlow
может потребоваться несколько минут (обычно не более пяти) на применение изменения.
Использование собственного пакета SDK или App-Auth
Azure AD B2C соответствует стандартам OAuth 2.0 для учетных данных пароля владельца ресурса общедоступного клиента и должен быть совместим с большинством клиентских пакетов SDK. См. последние рекомендации по реализации собственного пакета SDK для приложений OAuth 2.0 и OpenID Connect.
Следующие шаги
Вы можете скачать рабочие примеры, настроенные для использования с Azure AD B2C, на сайте GitHub для Android и iOS.