msal.js angular 6 SPA обратный вызов и обработка ошибок - PullRequest
0 голосов
/ 27 ноября 2018

Я использую 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 ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...