Вход в Azure B2C с Cypress oauth 2.0 — {tenant}.b2clogin.com

В настоящее время я пытаюсь реализовать тест Cypress e2e, в котором Azure B2C AD используется в качестве внешнего поставщика удостоверений. Итак, сначала я попытался посетить страницу входа в систему, как это сделал бы обычный пользователь, с помощью:

cy.get('#loginButton').click();
// this will visit: 
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize?...
cy.wait(2000);
cy.get('input').first().type(email).should('have.value', email);
cy.get('[id = "password"]').type(password).should('have.value', password);
cy.get('#next').click();
// should now redirect me to my app with the access token in my local storage

Но затем я получаю следующую ошибку:

{statusCode: 401, message: "Unauthorized"}

Пока я делаю это сам, внутри браузера все работает отлично. Кипарис не может этого сделать. Затем я узнал, что Cypress не может принимать состояние с внешних веб-сайтов, и мне нужно получить токен входа с помощью cy.request() и внедрить его в свое приложение:

https://github.com/cypress-io/cypress/issues/1342

Учебное пособие. Аутентификация Azure AD в тестах Cypress с помощью MSAL

Пример кода

Проблема здесь в том, что они использовали:

https://login.microsoftonline.com/${Cypress.env('AZURE_TENANT_ID')}/oauth2/v2.0/token

но мое приложение использует:

https://${Cypress.env('AZURE_TENANT_NAME')}.b2clogin.com/${Cypress.env('AZURE_TENANT_NAME')}.onmicrosoft.com/${Cypress.env('AZURE_AD_LOGIN_POLICY_NAME')}/oauth2/v2.0/token

Я попытался адаптировать запрос учебника, но он у меня не работает:

  Cypress.Commands.add('login', () => {    
    cy.request({
      method: 'POST',
      url: `https://${Cypress.env('AZURE_AD_AUTH_TENANT')}.b2clogin.com/${Cypress.env('AZURE_AD_AUTH_TENANT')}.onmicrosoft.com/${Cypress.env('AZURE_AD_AUTH_LOGIN_POLICY_NAME')}/oauth2/v2.0/Token`,
      form: true,
      body: {
        grant_type: 'password',
        client_id: `${Cypress.env('AZURE_AD_AUTH_CLIENT_ID')}`,
        client_secret: Cypress.env('AZURE_AD_AUTH_CLIENT_SECRET'),
        scope: 'openid%20offline_access',
        username: Cypress.env('AZURE_USERNAME'),
        password: Cypress.env('AZURE_PASSWORD')
      },
    }).then((response) => {
      injectTokens(response);
    });

Этот запрос дает:

{
    "error": "invalid_request",
    "error_description": "AADB2C90055: The scope 'openid offline_access' provided in request must specify a resource, such as 'https://example.com/calendar.read'.\r\nCorrelation ID: 147e543e-7b12-4349-8917-ad7d97b4b7cd\r\nTimestamp: 2022-12-08 11:40:05Z\r\n"
}

К сожалению, я понятия не имею, что означает эта ошибка, какой URL мне нужно указать? Какое разрешение имеет пользователь для входа на сайт? Мне просто нужен токен, чтобы я мог посещать веб-сайт как авторизованный пользователь с помощью Cypress.

Я знаю, что здесь есть несколько сообщений с предложениями о том, как подойти к этому, но ни один из них не работает для моего URL-адреса с «.b2clogin.com» внутри, я думаю, это работает по-другому.

Вот 3 открытых URL-адреса, которые я могу вызвать:

https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/oauth2/v2.0/authorize
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{loginPolicy}/SelfAsserted
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{loginPolicy}/oauth2/v2.0/token
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
0
112
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я попытался воспроизвести то же самое в своей среде через Postman и получил следующие результаты:

Я зарегистрировал одно веб-приложение в своем клиенте B2C и добавил разрешения API, как показано ниже:

В манифесте обязательно включите неявный поток, как показано ниже:

Теперь я создал один пользовательский поток владельца ресурса, как показано ниже:

Когда я попытался получить токен с теми же параметрами через Postman, я получил ту же ошибку, что и ниже:

POST https://b2ctenantname.b2clogin.com/b2ctenantname.onmicrosoft.com/<ROPC_policyname>/oauth2/v2.0/token
grant_type:password
client_id:<App_ID>
client_secret:<secret>
scope:openid offline_access
username:<UPN_of_B2C user> 
password:xxxxxxxxxxxx

Ответ:

Чтобы устранить ошибку, вам необходимо указать идентификатор приложения в параметре scope.

Я успешно сгенерировал токены, изменив область действия, как показано ниже:

POST https://b2ctenantname.b2clogin.com/b2ctenantname.onmicrosoft.com/<ROPC_policyname>/oauth2/v2.0/token
grant_type:password
client_id:<App_ID>
client_secret:<secret>
scope:openid <App_ID> offline_access
username:<UPN_of_B2C user> 
password:xxxxxxxxxxxx

Ответ:

Если вы хотите получить токены доступа и идентификатора, включите параметр response_type, как показано ниже:

POST https://b2ctenantname.b2clogin.com/b2ctenantname.onmicrosoft.com/<ROPC_policyname>/oauth2/v2.0/token
grant_type:password
client_id:<App_ID>
client_secret:<secret>
scope:openid <App_ID> offline_access
response_type: token id_token
username:<UPN_of_B2C user> 
password:xxxxxxxxxxxx

Ответ:

В вашем сценарии измените значение параметра scope в своем коде, включив идентификатор приложения вместе с openid и offline_access.

Ссылка:

Настройка потока учетных данных владельца ресурса — Azure AD B2C | Майкрософт

Спасибо за быстрый ответ! Ваш совет с response_type, чтобы также получить id_token, был действительно полезен. Я создал новый поток для ROPC и смог воспроизвести ваш пример. Но токен, который я получаю с потоком ROPC, несовместим с моим приложением. Изучив JWT, который я получил с ответом ROPC, я увидел, что в нем отсутствуют некоторые параметры. Я добавил их, установив флажки в разделе «Azure AD B2C | Пользовательские потоки». После этого я наконец смог использовать id_token, чтобы получить активный сеанс для моего клиента. Большое спасибо!

Tobias J. 12.12.2022 20:26

Другие вопросы по теме