我试图让Angular 4应用程序正确使用Azure AD B2C进行隐式身份验证。我使用msal.js来尝试使其工作。我已经检查了非常有限的official sample code,但它没有实际用处,因为它使用弹出窗口登录,我想重新定向。登录使用Azure AD B2C从Angular应用程序和msal.js重定向
我现在拥有的是我在我的应用程序中注入的以下身份验证服务,应该负责所有身份验证。
import { Injectable } from '@angular/core';
import * as Msal from 'msal';
@Injectable()
export class AuthenticationService {
private tenantConfig = {
tenant: "example.onmicrosoft.com",
clientID: 'redacted (guid of the client),
signUpSignInPolicy: "b2c_1_signup",
b2cScopes: ["https://example.onmicrosoft.com/demo/read", "openid"]
}
private authority = "https://login.microsoftonline.com/tfp/" + this.tenantConfig.tenant + "/" + this.tenantConfig.signUpSignInPolicy;
private clientApplication: Msal.UserAgentApplication;
constructor() {
this.clientApplication = new Msal.UserAgentApplication(this.tenantConfig.clientID, this.authority, this.authCallback);
}
public login(): void {
this.clientApplication.loginRedirect(this.tenantConfig.b2cScopes);
}
public logout(): void {
this.clientApplication.logout();
}
public isOnline(): boolean {
return this.clientApplication.getUser() != null;
}
public getUser(): Msal.User {
return this.clientApplication.getUser();
}
public getAuthenticationToken(): Promise<string> {
return this.clientApplication.acquireTokenSilent(this.tenantConfig.b2cScopes)
.then(token => {
console.log("Got silent access token: ", token);
return token;
}).catch(error => {
console.log("Could not silently retrieve token from storage.", error);
return this.clientApplication.acquireTokenPopup(this.tenantConfig.b2cScopes)
.then(token => {
console.log("Got popup access token: ", token);
return token;
}).catch(error => {
console.log("Could not retrieve token from popup.", error);
this.clientApplication.acquireTokenRedirect(this.tenantConfig.b2cScopes);
return Promise.resolve("");
});
});
}
private authCallback(errorDesc: any, token: any, error: any, tokenType: any) {
console.log(Callback')
if (token) {
console.log("Id token", token);
}
else {
console.log(error + ":" + errorDesc);
}
this.getAuthenticationToken();
}
}
但它不工作。我正确地获得了ID令牌,并且它是有效的,所以“Id令牌”确实收到了我可以使用的值,但是时间有限。
问题是当我尝试获取身份验证令牌时。第一个电话,到返回一个错误,说:Token renewal operation failed due to timeout: null
。
然后,我得到一个弹出窗口,要求输入用户名和密码,过了一会消失,我收到一条错误消息,说User does not have an existing session and request prompt parameter has a value of 'None'.
。
编辑:
所以,我想我明白发生了什么究竟怎么回事,重现上一个示例应用程序,你可以得到这里的问题:https://github.com/Gimly/NetCoreAngularAzureB2CMsal
如果从网页连接,然后转到fetchData页面(具有天气预报的页面),您可以看到验证令牌被正确兑换(打开浏览器控制台以获取所有日志)。但是,如果直接在fetchData上刷新页面,则可以看到与我描述的行为相同的行为,其中因超时错误而失败。
我最好的猜测是,由于某种原因,即使getUser
返回一个正确的值,在调用getAuthenticationToken
之前msal并未完全初始化,这是它完全失败的原因。
现在真正的问题......我如何确保它在尝试获取令牌之前完全初始化?
我想知道会发生什么[如果你尝试localStorage](https://stackoverflow.com/questions/45201872/how-to-use-localstorage-with-msal-js)? – spottedmahn
@spottedmahn刚刚尝试过,它的行为是一样的。 – Gimly
@spottedmahn我发现了更多关于这个问题的信息,你能检查我的编辑吗? – Gimly