#node.js #authentication #azure-active-directory #msal
#node.js #аутентификация #azure-active-directory #msal
Вопрос:
Я использую @azure/msal-node
пакет в приложении узла, чтобы мои пользователи могли входить в систему, используя свои учетные данные AzureAD. Вход в систему и получение токенов сеанса работают нормально, но я не могу найти способ аннулировать сеанс / выйти из пользователя — я упускаю из виду что-то очевидное здесь?
Просто для контекста, вот как я получаю свои токены:
// msalConfig is my valid config object
const msalApp = new msal.ConfidentialClientApplication(msalConfig);
const authCodeUrlParameters = {
scopes: ['user.read'],
redirectUri: BASE_URL '/msal-redirect'
};
try {
const authCodeResponse = await msalApp.getAuthCodeUrl(authCodeUrlParameters);
reply.redirect(authCodeResponse);
} catch (e) {
logError('auth code redirect error', e);
}
В обработчике перенаправления я делаю это:
const tokenResponse = await msalApp.acquireTokenByCode({
code: request.query.code,
scopes: ['user.read'],
redirectUri: BASE_URL '/msal-redirect'
});
и затем я использую этот токен для отображения зарегистрированного пользователя и т.д.
Чего мне не хватает, так это чего-то вроде msalApp.logout()
— чего я здесь не вижу?
Комментарии:
1. вы каким-то образом решили?
2. @Gianmarco В итоге я перенаправил свои запросы на выход сюда: login.microsoftonline.com/common/oauth2/v2.0/logout Это метод грубой силы, который полностью выводит пользователя из Azure AD. Я полагаю, что есть URL-адрес выхода для выхода пользователей только из вашего конкретного приложения, но, похоже, я не могу найти его прямо сейчас.
Ответ №1:
К сожалению, MSAL в настоящее время не содержит msalApp.logout()
API. Вместо этого вам придется вручную выполнить шаги.
Операция выхода из системы будет содержать несколько шагов:
- Удаление учетной записи и токенов из кэша приложений msal.
- Перенаправление на конечную точку выхода из системы AAD, чтобы пользователь вышел из системы, а файлы cookie AAD были удалены.
- Если у вашего веб-приложения есть сеанс, сделайте его недействительным.
Для удаления учетной записи и токенов из кэша приложений msal вы можете сделать что-то вроде:
const accounts = msalApp.getTokenCache().getAllAccounts();
// filter on the account that you want to delete from the cache.
// I take the first one here to keep the code sample short
const account = accounts[0];
msalApp.getTokenCache().removeAccount(account);
Для выхода из AAD вам нужно перенаправить пользователя на конечную точку выхода из Azure AD. Документация здесь должна объяснить, как обработать этот запрос.
Комментарии:
1. Спасибо! Тем временем я нашел конечную точку выхода из системы, но пропустил часть об удалении учетной записи из кэша токенов приложения. Однако, похоже, что эту функциональность было бы достаточно легко реализовать на стороне библиотеки MSAL, а выход из системы является неотъемлемой частью жизненного цикла сеанса пользователя.
2. Я пытался таким образом, но, похоже, removeAccount не работает, я все равно могу выполнить silentLogin, даже если я выхожу из системы
3. @Gianmarco пожалуйста, откройте проблему в github.com/AzureAD/microsoft-authentication-library-for-js с шагами для воспроизведения.
4. Не работает:
(node:20920) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1).
Ответ №2:
В ответе sgonzalez я вижу ошибку в «учетных записях». Эта константа является обещанием:
const accounts = msalApp.getTokenCache().getAllAccounts(); // <- is a Promisse
// filter on the account that you want to delete from the cache.
// I take the first one here to keep the code sample short
const account = accounts[0];
msalApp.getTokenCache().removeAccount(account);
Исправление:
pca.getTokenCache().getAllAccounts().then((response) => {
const account = response[0];
pca.getTokenCache().removeAccount(account).then(() => {
res.sendStatus(200);
}).catch((error) => {
res.status(500).send({error});
});
}).catch((error) => {
res.status(500).send(error);
});
Я не знаю, лучший ли это способ его реализации, но у меня это сработало.