Я использую msal.js на угловом 6 SPA для обработки аутентификации, у меня есть несколько проблем: во-первых, я не смог найти ясный пример того, как обрабатывать ошибки с помощью lib, поэтому я выбирал вещи влево и вправо,и я пришел к следующему результату:
@Injectable()
export class AuthenticationService {
_clientApplication: Msal.UserAgentApplication;
_clientApplicationPR: Msal.UserAgentApplication;
private _authority: string;
constructor(private apiService: ApiService, private backendRoutes: BackendRoutes) {
this._authority = `https://login.microsoftonline.com/tfp/${environment.tenant}/${environment.signUpSignInPolicy}`;
this._clientApplication =
new Msal.UserAgentApplication(
environment.clientID,
this._authority,
this._authCallback,
{
cacheLocation: 'localStorage',
redirectUri: window.location.origin
});
}
private _authCallback(errorDesc: any, token: any, error: any, tokenType:
any) {
console.log("in call back");
if (token) {
this.addUser();
} else {
// console.log(`${error} - ${errorDesc}`);
if (errorDesc.indexOf("AADB2C90118") > -1) {
//Forgotten password
this._clientApplicationPR = new Msal.UserAgentApplication(
environment.clientID,
`https://login.microsoftonline.com/tfp/${environment.tenant}/${environment.passResetPolicy}`,
this._authCallback,
{
cacheLocation: 'localStorage',
redirectUri: window.location.origin
});
this._clientApplicationPR.loginRedirect(environment.b2cScopes);
} else if (errorDesc.indexOf("AADB2C90077") > -1) {
//Expired Token
this._clientApplication.acquireTokenRedirect(environment.b2cScopes);
}
}
}
getAuthenticationToken(): Promise<string> {
return
this._clientApplication.acquireTokenSilent(environment.b2cScopes)
.then(token => token)
.catch(error => {
return Promise.reject(error);
});
}
}
Функция getAuthenticationToken используется в моем httpinterceptor для установки токена носителя.Это работает нормально, за исключением случаев, когда мой токен истекает, выдавая следующую ошибку:
main.c20e047e67b91051727f.js: 1 AADB2C90077: у пользователя нет существующего сеанса, а параметр запроса запроса имеет значение «Нет»».Идентификатор корреляции: 3a627592-5ab0-4e54-b01d-e4296e4d4002 Отметка времени: 2018-11-27 08: 30: 32Z | Interaction_required
В моей попытке обработать этот случай вы можете увидеть обратный вызов, проверяющийсодержание кода ошибки.Проблема в том, что мой обратный вызов никогда не вызывается после сбоя acquTokenSilent ... Интересно, почему и если я делаю что-то не так?Я полагаю, что для acquTokenSilent вы можете обработать ошибку и отклонить обещание.Хотя это и не идеально.
Во-вторых, контекст в обратном вызове не совпадает с контекстом моего служебного, у меня нет доступа к «this», из того, что я прочитал, он перезаписывается библиотекой.Мой временный хак для "AADB2C90118 ошибка забытого пароля", это грязное создание нового userAgentAplication с соответствующими полномочиями, есть ли способ получить доступ к контексту моей службы в обратном вызове и избежать этого?
Edit «this» ссылается на само userAgentApplication в обратном вызове, поэтому вместо создания нового вы можете сделать что-то вроде этого:
constructor(private apiService: ApiService, private backendRoutes: BackendRoutes) {
this._authority = `https://login.microsoftonline.com/tfp/${environment.tenant}/${environment.signUpSignInPolicy}`;
this._clientApplication =
new Msal.UserAgentApplication(
environment.clientID,
this._authority,
this.msalHandler,
{
cacheLocation: 'localStorage',
redirectUri: window.location.origin
});
}
msalHandler(errorDesc: any, token: any, error: any, tokenType: any) {
let userAgent: Msal.UserAgentApplication = <any>(this);
if (errorDesc.indexOf("AADB2C90118") > -1) {
//Forgotten password
userAgent.authority = `https://login.microsoftonline.com/tfp/${environment.tenant}/${environment.passResetPolicy}`;
userAgent.loginRedirect(environment.b2cScopes);
} else if (errorDesc.indexOf("AADB2C90077") > -1) {
//Expired Token
this.logout();
}
}
ИЛИ привязать это к вашему callBack:
this._clientApplication =
new Msal.UserAgentApplication(
environment.clientID,
this._authority,
this.msalHandler.bind(this),
{
cacheLocation: 'localStorage',
redirectUri: window.location.origin
});
и мой перехватчик:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.authenticationService.getAuthenticationToken()
.then(token => {
return req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
})
.catch(err => {
this.authenticationService.msalHandler(err,null,null,null);
return req;
}))
.switchMap(req => {
return next.handle(req);
});
}
Для информации я использую последнюю версию "msal": "^ 0.2.3", "typcript": "~ 2.7.2", "@angular/ core ":" ^ 6.0.3 ".