[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:
Library version: 1.2.0-beta.2
Sometimes I can login successfully, but other times it fails and it shows a login is "InProgress" in my Session Storage. Clearing cookies or clearing session storage won't fix it, but clearing both will. Opening in "Incognito" mode or "InPrivate" mode will also fix it.
Should I be detecting this weird state and trying to programmatically clear the session storage and cookies?
It should either log in correctly every time, or it should automatically clear the session state and cookies, or whatever it needs to clear.
I still don't understand what is causing my logins to sometimes fail with the "InProgress" status so it's hard to give steps to reproduce.
Manually clearing session seems to work; still need to do more testing...
function logRedirectCallbackErrors(error: MSAL.AuthError, response: MSAL.AuthResponse | undefined) {
if (error) {
console.error("Redirect Callback Error: " + error);
setDeniedReason("Unable to login.")
setIsAccessDenied(true);
// Clear session to remove "login in process" error
sessionStorage.clear();
}
}
@JordanMarr Is this happening only with session storage or is it seen for local storage too? Is it possible to share your sample code for authentication so we can try reproducing the issue at our end?
@JordanMarr Is this happening only with
session storageor is it seen forlocal storagetoo? Is it possible to share your sample code for authentication so we can try reproducing the issue at our end?
My authentication code (as a React hook) is below (my tenant id and authority replaced with placeholders).
I know it's not exactly like the examples, but this is the best I could do to get it working.
import React, { useState, useEffect } from 'react';
import API from './api';
import * as MSAL from 'msal'
import { navigate } from 'hookrouter';
export interface IUser {
name: string,
email: string,
isPM: boolean,
isAdmin: boolean
}
export const useAuth = () => {
const msalConfig: MSAL.Configuration = {
auth: {
clientId: 'my tenant id',
authority: 'my authority'
},
cache: {
storeAuthStateInCookie: true
}
};
const tokenReq: MSAL.AuthenticationParameters = {
scopes: ["api://my tenant id/user_impersonation"]
};
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [isAccessDenied, setIsAccessDenied] = useState(false);
const [deniedReason, setDeniedReason] = useState("");
const [iuser, setIuser] = useState<IUser>({ name: "Not Authenticated", email: "-", isPM: false, isAdmin: false });
const addBearerTokenToRequests = (token: string) => {
API.interceptors.request.use(req => {
req.headers['Authorization'] = `Bearer ${token}`;
return req;
});
};
const handle401Errors = () => {
API.interceptors.response.use(resp => {
return resp;
}, error => {
if (error.response.status === 401) {
setDeniedReason(error.response.data);
setIsAuthenticated(false);
setIsAccessDenied(true);
console.error("401 Error: User is not authorized to access this resource. " + error);
}
throw error;
});
};
useEffect(() => {
handle401Errors();
authenticate();
}, []);
return { isAuthenticated, isAccessDenied, deniedReason, user: iuser, logout };
function urlContains(str: string) {
return window.location.href.indexOf(str) > -1;
}
async function authenticate() {
let msal = new MSAL.UserAgentApplication(msalConfig);
let acct = await msal.getAccount();
if (!acct) { // Users need to login
try {
console.log('Redirecting to login...');
// A handler is required or loginRedirect won't work.
msal.handleRedirectCallback(logRedirectCallbackErrors);
navigate('/'); // User must sign in from the root url (must match the redirect url configured in the Azure App Registration)
msal.loginRedirect(tokenReq);
} catch (err3) {
console.error(`Unable to authenticate: ${err3}`);
}
} else if (!urlContains('access_token')) { // user id exists - acquire token silently
try {
console.log('Acquiring a token silently...');
let resp = await msal.acquireTokenSilent(tokenReq);
if (resp.accessToken) {
console.log('Acquired an access token.');
setIuser({ ...iuser, name: resp.account.name, email: resp.account.userName });
addBearerTokenToRequests(resp.accessToken);
try {
// Get user with claims (isPM, isAdmin, etc)
const { data } = await API.get<IUser>('/api/auth/user');
// Update return values
setIsAuthenticated(true);
setIuser(data);
} catch (error) {
setDeniedReason(error.response.data);
setIsAuthenticated(false);
setIsAccessDenied(true);
}
} else {
console.error('Unable to obtain an access token.');
setIsAccessDenied(true);
}
} catch (err) {
try {
console.log('Redirecting to login...');
// A handler is required or loginRedirect won't work.
msal.handleRedirectCallback(logRedirectCallbackErrors);
navigate('/'); // User must sign in from the root url (must match the redirect url configured in the Azure App Registration)
msal.loginRedirect(tokenReq);
} catch (err2) {
console.error(`Unable to aquire an access token: ${err2}`);
setIsAccessDenied(true);
}
}
}
}
function logRedirectCallbackErrors(error: MSAL.AuthError, response: MSAL.AuthResponse | undefined) {
if (error) {
console.error("Redirect Callback Error: " + error);
setDeniedReason("Unable to login.")
setIsAccessDenied(true);
// Clear session to remove "login in process" error
sessionStorage.clear();
}
}
async function logout() {
let msal = new MSAL.UserAgentApplication(msalConfig);
msal.logout();
}
}
I ran into this today and found an easy way to repro.
The only way to successfully login after encountering this is as @JordanMarr said, delete sessionStorage and any cookies.
@AndrewCraswell Thanks for the steps. We are working on something similar to this (but for other error types) using #1024; the initial implementation has some flaws and I am working on fixing this. The PR is primarily to clean up intermittent cache which is created during login/token calls when the flow bails out in an error case.
What you brought up is an interesting edge case,msal js should be in this case able to identify a stale request since the NW is disconnected. Let me check if that is feasible and reach out.
Did you mean #1042? I had seen that PR earlier but for some reason thought it had already been merged.
Sorry yes. It is #1042. It isn't merged as I think our approach causes issues in some error cases. I will do a new version soon. But as I stated, the use case you mentioned is a corner case and with concurrent requests, we need to identify a stale request vs on going one which is tricky as we do not remember application state. Will reach out once I have a solution in place.
I was able to find another way to repro this issue in a bit more egregious way. These steps will break when using Redirect login method:
ClientAuthError with error code of login_progress_error.This example was done with sessionStorage.
See also:
https://github.com/syncweek-react-aad/react-aad/issues/160
Yes. The above example makes sense. Would you be able to test if I send a private build?
@sameerag Absolutely, would be happy to.
@sameerag Was this one of the items addressed in Beta 4? I'm assuming not since I can still repro it.
Weird question though, because we've hit this issue again in a new scenario with a corporate customer. On Edge browsers when the user initiates a login, the redirect to login.microsoftonline.com is prevented, and instead opens in a new instance of IE 11... Because of this when they complete the login flow in IE 11 the user receives login_in_progress which seems perfectly valid to me. This is a stretch, but have any of you encountered such an issue before? I'm guessing this company has some sort of group policy causing this. I'm still investigating whether this is something we can prevent on our side.
@AndrewCraswell beta-5 isn't released yet. We plan to do it tomorrow and release 1.2.0 around Dec 6-8th.
I did not come across the issue you mentioned on Edge browsers, I can check with my team and reach out.
beta release and a mainline release will follow soon.@sameerag is this issue fixed in beta?
I'm still having this issue in 1.2.0 with the redirect. I entered this state from a bad login and now it just loops. I'm using local storage. There are no cookies set when I encounter this and even if I clear local storage and make sure there are no cookies, I'm still stuck in the endless loop. Also, where is it documented that the redirect will return to the initiating page but with a #id_token stuck on my url?`
Per the comments above, I guess that once a cookie indicating login in progress gets set on the https://login.microsoftonline.com origin, it is never removed even if you signout and is passed to the login request from my app. Cleaning the login.microsoftonline.com cookie and origin storage for my app does fix the loop.
@aappddeevv The loop is probably triggered from AAD where if a given request after failing is retried multiple times. Since this issue is partially addressing the cache clean-up issues, it gets confusing to track a new use case with the same ticket.
Can you please:
Same applies for anyone following this thread. Please raise a new github issue helping us track different use cases clearly. Closing this ticket.
I have the same issue with B2C sometimes the app open a new login tab and AuthenticationState.InProgress keep in true. Sometimes the new tab is closed automatically after 3 or more minutes. @sameerag Should I open a new ticket?
I still meet the similar issue using react v1.2.1. The page don't redirect to the home page. Just stay on that page with url domain/#id_token=XXX. And status is inProgress in sessionStorage.

``` javascript
async componentDidMount() {
if (msalApp.urlContainsHash(window.location.hash) && isInIframe()) {
return null;
}
msalApp.handleRedirectCallback(error => {
if (error) {
const errorMessage = error.errorMessage ? error.errorMessage : "Unable to acquire access token.";
// setState works as long as navigateToLoginRequestUrl: false
this.setState({
error: errorMessage
});
}
});
const account = msalApp.getAccount();
this.setState({
account
});
if (!account && !msalApp.urlContainsHash(window.location.hash) && !msalApp.getLoginInProgress()) {
return this.onSignIn(true);
}
if (account) {
this.acquireTokens()
}
}
````
Got the exact same problem as @betterliyu. Why is it even closed?
Same problem as @betterliyu and @crobin1
I've noticed if you are already logged-in with your Azure AD account somewhere and then browse the web app secured by msal.js in the same browser session or another tab, it's stuck in "In Progress". But if you open another window of the same browser and try again, it works. Closing completely the browser and reopening it work as well.
@sameerag Could you reconsider this issue and reopen it?
@crobin1 Please open a new ticket and our livesite engineer would be happy to help you solve this. Thanks!
@crobin1 @tnorling Created one here: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/2071
Most helpful comment
Got the exact same problem as @betterliyu. Why is it even closed?