#angular #authentication #msal
Вопрос:
Здравствуйте, у меня есть регистрация приложения, которое поддерживает «Всех пользователей учетной записи Microsoft». Я пытался войти в систему из своего приложения Angular с 3 типами учетных записей для входа.
gt; 1. Microsoft tenant users - Successfully logging-in gt; 2. Microsoft Personal account users i.e. hotmail/outlook.com accounts - Successfully logging-in gt; 3. Other organization accounts. - Getting BrowserAuthError: interaction_in_progress: Interaction is currently in progress
Inside app.module.ts file const isIE = window.navigator.userAgent.indexOf("MSIE ") gt; -1 || window.navigator.userAgent.indexOf("Trident/") gt; -1; // Remove this line to use Angular Universal export function loggerCallback(logLevel: LogLevel, message: string) { //console.log(message); } export function MSALInstanceFactory(): IPublicClientApplication { return new PublicClientApplication({ auth: { clientId: authConfig.clientId, authority: authConfig.authority, redirectUri: authConfig.redirectUri, }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, storeAuthStateInCookie: isIE, }, system: { loggerOptions: { loggerCallback, logLevel: LogLevel.Info, piiLoggingEnabled: false } } }); } export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration { const protectedResourceMap = new Maplt;string, Arraylt;stringgt;gt;(); // protectedResourceMap.set(authConfig.graphEndpoint, ['user.read']); protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read']); protectedResourceMap.set(`${environment.API_URL}*/*`, authConfig.consentScopes); return { interactionType: InteractionType.Redirect, protectedResourceMap }; } export function MSALGuardConfigFactory(): MsalGuardConfiguration { return { interactionType: InteractionType.Redirect, authRequest: { scopes: ['user.read'] }//, //loginFailedRoute: '/login-failed' }; } async ngOnInit(): Promiselt;voidgt; { this.isIframe = window !== window.parent amp;amp; !window.opener; // Remove this line to use Angular Universal this.setLoginDisplay(); this.msalBroadcastService.inProgress$ .pipe( filter((status: InteractionStatus) =gt; status === InteractionStatus.None), takeUntil(this._destroying$) ) .subscribe(() =gt; { this.setLoginDisplay(); this.checkAndSetActiveAccount(); }) } checkAndSetActiveAccount(){ /** * If no active account set but there are accounts signed in, sets first account to active account * To use active account set here, subscribe to inProgress$ first in your component * Note: Basic usage demonstrated. Your app may require more complicated account selection logic */ let activeAccount = this.authService.instance.getActiveAccount(); if (!activeAccount amp;amp; this.authService.instance.getAllAccounts().length gt; 0) { let accounts = this.authService.instance.getAllAccounts(); this.authService.instance.setActiveAccount(accounts[0]); } } loginRedirect() { if (this.msalGuardConfig.authRequest){ this.authService.loginRedirect({...this.msalGuardConfig.authRequest} as RedirectRequest); } else { this.authService.loginRedirect(); } } loginPopup() { if (this.msalGuardConfig.authRequest){ this.authService.loginPopup({...this.msalGuardConfig.authRequest} as PopupRequest) .subscribe((response: AuthenticationResult) =gt; { this.authService.instance.setActiveAccount(response.account); }); } else { this.authService.loginPopup() .subscribe((response: AuthenticationResult) =gt; { this.authService.instance.setActiveAccount(response.account); }); } } logout(popup?: boolean) { if (popup) { this.authService.logoutPopup({ mainWindowRedirectUri: "/" }); } else { this.authService.logoutRedirect(); } } ngOnDestroy(): void { this._destroying$.next(undefined); this._destroying$.complete(); } Inside app.component.ts file setLoginDisplay() { this.loginDisplay = this.authService.instance.getAllAccounts().length gt; 0; } this.msalBroadcastService.inProgress$ .pipe( filter((status: InteractionStatus) =gt; status === InteractionStatus.None), takeUntil(this._destroying$) ) .subscribe(() =gt; { this.setLoginDisplay(); this.checkAndSetActiveAccount(); }) checkAndSetActiveAccount(){ /** * If no active account set but there are accounts signed in, sets first account to active account * To use active account set here, subscribe to inProgress$ first in your component * Note: Basic usage demonstrated. Your app may require more complicated account selection logic */ let activeAccount = this.authService.instance.getActiveAccount(); if (!activeAccount amp;amp; this.authService.instance.getAllAccounts().length gt; 0) { let accounts = this.authService.instance.getAllAccounts(); this.authService.instance.setActiveAccount(accounts[0]); } } loginRedirect() { if (this.msalGuardConfig.authRequest){ this.authService.loginRedirect({...this.msalGuardConfig.authRequest} as RedirectRequest); } else { this.authService.loginRedirect(); } } loginPopup() { if (this.msalGuardConfig.authRequest){ this.authService.loginPopup({...this.msalGuardConfig.authRequest} as PopupRequest) .subscribe((response: AuthenticationResult) =gt; { this.authService.instance.setActiveAccount(response.account); }); } else { this.authService.loginPopup() .subscribe((response: AuthenticationResult) =gt; { this.authService.instance.setActiveAccount(response.account); }); } } logout(popup?: boolean) { if (popup) { this.authService.logoutPopup({ mainWindowRedirectUri: "/" }); } else { this.authService.logoutRedirect(); } } ngOnDestroy(): void { this._destroying$.next(undefined); this._destroying$.complete(); } setLoginDisplay() { this.loginDisplay = this.authService.instance.getAllAccounts().length gt; 0; }
Мы используем одну и ту же конфигурацию, и все одинаково для всех аутентификаций входа в систему. Но только для учетных записей организаций отображается эта ошибка. Пожалуйста, посоветуйте, так как я новичок в аутентификации в Angular
Ответ №1:
Вы получаете эту ошибку из-за этого кода: msalInstance.loginRedirect(loginRequest);
Этот фрагмент кода проверит хранилище сеансов на наличие ключевых и других временных значений, необходимых для процесса перенаправления, и если значения существуют и значения равны, то это произойдет через исключение interaction_in_progress
Попробуйте настроить код так, чтобы он выглядел следующим образом:
// authRedir.ts await msalInstance.handleRedirectPromise(); // mySignInPage.ts (or userprofile.vue, or whatever page invokes a sign-in) await msalInstance.handleRedirectPromise(); async signIn(){ const loginRequest: msal.RedirectRequest = { scopes: ["openid", "profile", "offline_access","your_other_scopes"] redirectUri: "http://localhost:8080/authredirect" }; const accounts = msalInstance.getAllAccounts(); if (accounts.length === 0) { await msalInstance.loginRedirect(); } }
Не забудьте проверить всю асинхронность/ожидание, где бы вы ни называли это в своем приложении.