Cypress с Azure AD (MSAL)

Я новичок в Cypress и Azure AD, но я выполнял шаги, описанные здесь, чтобы создать тесты Cypress для существующего приложения Angular, которое использует Azure AD. В нем упоминается, что они используют ADAL, но в нашем приложении используется MSAL, который, по его словам, должен быть аналогичным. Однако я изо всех сил пытаюсь заставить его работать. Вот моя функция входа в систему:

const tenant = 'https://login.microsoftonline.com/{my_tenant_id}/';
const tenantUrl = `${tenant}oauth2/token`;
const clientId = '{my_app_id}';
const clientSecret = '{my_secret}';
const azureResource = 'api://{my_app_id}';
const knownClientApplicationId = '{client_application_id_from_manifest}';
const userId = '{user_identifier}';
    
export function login() {
    cy.request({
        method: 'POST',
        url: tenantUrl,
        form: true,
        body: {
            grant_type: 'client_credentials',
            client_id: clientId,
            client_secret: clientSecret,
            resource: azureResource
        }
    }).then(response => {
        const Token = response.body.access_token;
        const ExpiresOn = response.body.expires_on;
        const key = `{"authority":"${tenant}","clientId":"${knownClientApplicationId}","scopes":${knownClientApplicationId},"userIdentifier":${userId}}`;
        const authInfo = `{"accessToken":"${Token}","idToken":"${Token}","expiresIn":${ExpiresOn}}`;
    
        window.localStorage.setItem(`msal.idtoken`, Token);
        window.localStorage.setItem(key, authInfo);
}
Cypress.Commands.add('login', login);

Когда я запускаю это, возвращается токен доступа. Когда я проверяю локальное хранилище после обычного запроса браузера, у него гораздо больше полей, таких как msal.client.info (значение authInfo в приведенном выше коде также должно содержать это значение), но я не знаю, откуда взять эту информацию.

Конечным результатом является то, что запрос POST, кажется, возвращается успешно, но тесты Cypress все еще считают пользователя неаутентифицированным.

Существующее приложение реализует CanActivate службу, которая проходит, если MsalService.getUser() возвращает действительного пользователя. Как я могу убедить эту службу, что мой пользователь Cypress действителен?

Обновлять:

После некоторых экспериментов со значениями локального хранилища выяснилось, что для прохождения входа в систему требуется только два значения:

msal.idtoken
msal.client.info

Первый у меня уже есть; во втором я не уверен, но он кажется, чтобы каждый раз возвращать одно и то же значение. На данный момент я жестко кодирую это значение в своих тестах, и, похоже, оно работает:

then(response => {
    const Token = response.body.access_token;

    window.localStorage.setItem(`msal.idtoken`, Token);
    window.localStorage.setItem(`msal.client.info`, `{my_hard_coded_value}`);
});

Единственная незначительная проблема сейчас заключается в том, что метод MsalService.getUser() возвращает немного другие значения, чем ожидает приложение (например, displayableId и name отсутствуют; idToken.azp и idToken.azpacr новые). Я буду исследовать дальше ...


person Michael McMullin    schedule 26.09.2020    source источник
comment
msal.client.info имеет значение в кодировке base 64 идентификатора пользователя и идентификатора клиента. Вы можете сослаться на этот код для примера значения Client_info ссылки. Если вы декодируете значение, вы можете получить информацию об uid и utid. Что касается отсутствующих утверждений, видите ли вы эти утверждения (например, displayableId и name) в токене Id, который вы получили от лазурного объявления? Вы можете проверить, что это jwt.ms URL.   -  person Dhivya G - MSFT Identity    schedule 30.09.2020


Ответы (2)


Я хочу поблагодарить вас за всю работу, которую вы проделали, чтобы выяснить, какие переменные устанавливать при работе с MSAL! Думаю, я могу помочь выяснить, откуда берется clientInfo. Похоже, он генерируется из clientId, что объясняет, почему это всегда одно и то же значение:

static createClientInfoFromIdToken(idToken:IdToken, authority: string): ClientInfo {
        const clientInfo = {
            uid: idToken.subject, 
            utid: ""
        };

        return new ClientInfo(CryptoUtils.base64Encode(JSON.stringify(clientInfo)), authority);
    }

См. Источник здесь: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/70b87bcd27bfe67789c92b9bc046b45733f490ed/lib/msal-core/srfrerc/ClientInfo.ts

Я смог использовать ваш код и просто добавил import * as MSAL from "@azure/msal-browser" и window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);

Сработало для меня как шарм!

person Kimberly Ly    schedule 16.10.2020
comment
Сталкивались ли вы с какими-либо проблемами с acquTokenSilent? Я сделал это, и мне удалось передать логин, но он терпит неудачу, когда пытается получить токен с помощью acquTokenSilent. - person Manuel Castro; 27.03.2021
comment
Токен получен, но в строке MSAL.clientInfo я получаю сообщение об ошибке: ClientAuthError: информация о клиенте не может быть правильно проанализирована / декодирована. Просмотрите трассировку, чтобы определить основную причину. Ошибка: ошибка: недопустимая строка base64 stackoverflow.com/questions/67716105/ - person Vaibhav Sawant; 27.05.2021

Это решение принесло мне успешный запрос, но я все еще не мог пройти через экран входа в систему в моем приложении, после некоторого поиска я нашел это отличное обучающее видео, которое помогло мне пройти экран входа в систему! Я использую пакеты msal-react & msal-browser npm.

https://www.youtube.com/watch?v=OZh5RmCztrU

Репо для кода здесь:

https://github.com/juunas11/AzureAdUiTestAutomation/tree/main/UiTestAutomation.Cypress/cypress

person Jack David Evans    schedule 08.07.2021