问题
I have an Angular web application that is using @microsoft/microsoft-graph-client to get the logged in user's information. @azure/msal-angular is used to sign-in the user. I have an auth service that logs the user in with this:
async signIn(): Promise<void> {
const result = await this.msalService.loginPopup(OAuthSettings.consentScopes)
.catch((reason) => {
this.alertsService.add('Login failed', JSON.stringify(reason, null, 2));
});
if (result) {
this.authenticated = true;
await this.getUser();
}
}
private async getClient(): Promise<Client> {
const graphClient = Client.init({
// Initialize the Graph client with an auth
// provider that requests the token from the
// auth service
authProvider: async (done) => {
const token = await this.getAccessToken()
.catch((reason) => {
done(reason, null);
});
if (token) {
done(null, token);
} else {
done('Could not get an access token', null);
}
}
});
return graphClient;
}
private async getUser() {
if (!this.authenticated) {
return null;
}
const graphClient = await this.getClient();
// Get the user from Graph (GET /me)
const graphUser = await graphClient.api('/me').get();
console.log('USERNAME: ', graphUser.displayName);
sessionStorage.setItem('d365dataportal.user', graphUser);
if (graphUser.mail != null) {
sessionStorage.setItem('d365dataportal.user.email', graphUser.mail);
} else {
sessionStorage.setItem('d365dataportal.user.email', graphUser.userPrincipalName);
}
sessionStorage.setItem('d365dataportal.user.avatar', graphUser.avatar);
sessionStorage.setItem('d365dataportal.user.name', graphUser.displayName);
}
My OAuthSettings look like this:
export const OAuthSettings = {
appId: 'App GUID from Azure Here',
redirectUri: 'http://localhost:4200',
consentScopes: ['user.read',
'Directory.Read.All',
'Directory.ReadWrite.All',
'Directory.AccessAsUser.All']
};
The problem I am running into is that when this.msalService.loginPopup() is called, the entire application hangs, the popup window never shuts, and never seems to authenticate and redirect back to my page. I am not sure why this is happening. Can anyone see any glaring errors?
EDIT
I am leaving the content above because it was my original question. I realized that the issue had nothing to do with my original title and changed the name of the question.
回答1:
I solved my problem, and it had nothing to do with using Azure AD or Graph API. In my component html, I had an *ngIf that was looking for the result of a function. It looked like this:
<a mat-list-item *ngIf="authService.functionThatReturnsBoolean()" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>
Instead, I changed my service to populate the results in a property in the service and pointed the *ngIf at that property like this:
<a mat-list-item *ngIf="authService.booleanProperty" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>
The problem had to do with the way Angular continues to look for the status in the *ngIf. It was then stuck in what appeared to be an endless loop until Chrome crashed.
回答2:
I made some debugging and I think there's either a bug or feature that I don't understand in MSAL. If you look at the UserAgentApplication.js from MSAL library there's this function called loginPopupHelper();
I think problem is there. If you look at this.authorityInstance.ResolveEndpointsAsync()
successful callback function you find this if block
if (popUpWindow) {
_this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
popUpWindow.location.href = urlNavigate;
}
It's clearly redirecting that popup window to your redirect url. And it will never close that popup window like fail callback does. My quick and dirty fix was to modify it like so
if (popUpWindow) {
_this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
window.location.href = urlNavigate;
popUpWindow.close();
}
It goes without saying that this is not stable solution because whenever you update that library this will be overwritten I guess. Also this doesn't fire a popup anymore but redirects to MS login page and then back when credentials are given. I have a clue why that happens but doesn't have time right now. I think I'll start a conversation about this in Github if not already discussed there.
But yeah, that's what I was able to find.
EDIT: Actually there are already something related to this in Github. For example
https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/545
https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/479
来源:https://stackoverflow.com/questions/54412692/angular-application-stuck-in-an-endless-loop