问题
I have an angular application hosted in Azure web app. I have selected azure active directory as the authentication provider and if the request is not authenticated then it should log in with the same. So, basically, if the user is already logged in with his/her Microsoft account then he/she does not need to log in again.
As per now, I am using .auth/me to get all the user-related details such as givenName, email, etc. Now, I have a requirement to display the user's outlook profile picture. For this, I tried using Graph API with MSAL and when I use the below code then it is working fine: -
async signIn(): Promise<void> {
let result = await this.msalService.loginPopup(OAuthSettings.scopes)
.catch((reason) => {
this.alertsService.add('Login failed', JSON.stringify(reason, null, 2));
});
if (result) {
this.authenticated = true;
this.user = await this.getUser();
}
}
async getAccessToken(): Promise<string> {
let result = await this.msalService.acquireTokenSilent(OAuthSettings.scopes)
.catch((reason) => {
this.alertsService.add('Get token failed', JSON.stringify(reason, null, 2));
});
return result;
}
private async getUser(): Promise<User> {
if (!this.authenticated) return null;
let graphClient = Client.init({
authProvider: async(done) => {
let token = await this.getAccessToken()
.catch((reason) => {
done(reason, null);
});
if (token)
{
done(null, token);
} else {
done("Could not get an access token", null);
}
}
});
let graphUser = await graphClient.api('/me').get();
let user = new User();
user.displayName = graphUser.displayName;
user.email = graphUser.mail || graphUser.userPrincipalName;
return user;
}
Since I don't want any user prompt, I slightly changed my signIn() method to avoid any user prompt like below: -
async signIn(): Promise<void> {
let result = this.msalService.loginRedirect(OAuthSettings.scopes);
this.user = await this.getUser();
}
After changing to this, it is redirecting to login.microsoft.com in an infinite loop. I am unable to find any way to avoid any kind of prompt or redirection to get all the user-related details including the profile photo. Please suggest some way to achieve this. My current working code for getting user name without any user prompt is given below: -
getUserName(): Observable<any> {
return this._http
.get<any>(this.myAppUrl + '.auth/me', {
withCredentials: true
})
.pipe(catchError(this.errorHandler));
}
回答1:
Since you have already used easy auth with your App service, you can get the access token directly without logging in again.
What you need to do is configuring web app to ask for access to graph api resource. Go to the azure resource explorer-> go under the site node and go to /config/authsettings.
Click the edit button, and change the client secret to the secret your AAD Application has configured under the advanced authentications settings.
In addition to adding client secret, change the additionaloginparams to the following
["response_type=code id_token", "resource=https://microsoft.graph.com"]
Then your app service auth should start receiving the X-MS-TOKEN-AAD-ACCESS-TOKEN header which you can utilize to access the Microsoft Graph API.
Reference:
Configuring an App Service to get an Access Token for AAD Graph API
来源:https://stackoverflow.com/questions/59559571/get-user-details-with-azure-active-directory-as-authentication-provider