【问题标题】:ClientAuthError: Token renewal operation failed due to timeout MSAL AngularClientAuthError:由于 MSAL Angular 超时,令牌更新操作失败
【发布时间】:2020-11-03 18:10:31
【问题描述】:

我是非常新的 MSAL。所以我只遵循从这里https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/README.md 实施它的基本设置。

我所做的是像这样在 app.module 中设置配置

    MsalModule.forRoot({
      auth: {
        clientId: 'myclientid', // This is your client ID
        authority: 'https://login.microsoftonline.com/mytenantid', // This is your tenant ID
        redirectUri: 'http://localhost:4200'// This is your redirect URI
       
      },
      cache: {
        cacheLocation: 'sessionStorage',
        storeAuthStateInCookie: isIE, // Set to true for Internet Explorer 11
      },
    }, {
      popUp: !isIE,
      consentScopes: [
                  'user.read',
                  'openid',
                  'apiappid/user_impersonation',
                ], 
      unprotectedResources: [],
      protectedResourceMap: [
                  [
                    'https://localhost:44331/',
                    ['apiappid/user_impersonation'],
                  ]
                  
                ], 
      extraQueryParameters: {}
    })

在路由文件中添加了这个

 {path : 'das',canActivate: [MsalGuard], component:CrMainComponent},

这是我的 app.component.ts

import {
  Component,
  Injectable
} from '@angular/core';
import {
  Observable,
  Subscription
} from 'rxjs';

import {
  BroadcastService,
  MsalService
} from '@azure/msal-angular';
import {
  CryptoUtils,
  Logger,
  AuthError,
  AuthResponse
} from 'msal';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'angular-client';
  loggedIn: boolean;

  public userInfo: any = null;
  private subscription: Subscription;
  public isIframe: boolean;

  constructor(private broadcastService: BroadcastService, private authService: MsalService) {

    this.isIframe = window !== window.parent && !window.opener;

    if (this.authService.getAccount())

    {
      //console.info(JSON.stringify(this.authService.getAccount()));
      this.loggedIn = true;

    } else {

      this.loggedIn = false;
      //this.login();

    }
  }
  login()

  {

    const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;

    if (isIE) {
      this.authService.loginRedirect();

    } else {

      this.authService.loginPopup();

    }
  }

  logout()
  {
    this.authService.logout();

  }
  ngOnInit() {

    this.broadcastService.subscribe("msal:loginFailure", (payload) => {

      console.log("login failure " + JSON.stringify(payload));

      this.loggedIn = false;

    });

    this.broadcastService.subscribe("msal:loginSuccess", (payload) => {
      console.log("login success " + JSON.stringify(payload));
      this.loggedIn = true;
      //alert("Login Success");

    });
    this.authService.handleRedirectCallback((redirectError: AuthError, redirectResponse: AuthResponse) => {
      if (redirectError) {
        console.error("Redirect error: ", redirectError);
        return;
      }

      console.log("Redirect success: ", redirectResponse);
    });
  }

  ngOnDestroy() {

    this.broadcastService.getMSALSubject().next(1);
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

所以我猜,因为我将 Msalguard 指定给我的路由配置,它重定向到 Azure AD 身份验证的微软,并且在成功的身份验证时,它会将我重定向回我的页面。一切正常。

但有时我会遇到错误

Uncaught (in promise): ClientAuthError: Token renewal operation failed due to timeout.

老实说,我不知道我错过了什么或我做错了什么。在我的任何代码中,我都没有对登录过程进行任何操作。当我有这些代码时,这一切都会自动发生。那么我们真的会做些什么来解决这个令牌更新问题吗?我的意思是我们需要手动更新令牌吗?如果有怎么办??

【问题讨论】:

    标签: angular jwt azure-active-directory msal


    【解决方案1】:

    对于超时错误,使用相同的范围调用acquireTokenPopup,然后再次发出请求。可以参考this

    这是续订问题的已知问题。您可以跟踪问题here

    如果你想为 Angular 使用 MSAL,请参考sample

    【讨论】:

      【解决方案2】:

      使用以下代码避免令牌更新操作。

      this.authService.acquireTokenPopup(requestObj).then(function (tokenResponse) {
        // Callback code here
        console.log(tokenResponse.accessToken);
      }).catch(function (error) {
        console.log(error);
      });
      

      不要使用 => this.authService.acquireTokenSilent

      这是一种解决方法,此处为实际问题跟踪https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1592

      【讨论】:

        【解决方案3】:

        其他答案不直接回答问题。在阅读了答案并研究了这个问题后,我在here 的问题跟踪链接中找到了一个适合我的解决方案(如其他答案中提供的那样)。问题仍然存在,但过了一会儿,它似乎自行修复并让我重新进行身份验证。告诉人们去看 angular 示例是没有用的,因为它不包含解决此问题的代码。

        @NgModule({
          imports: [RouterModule.forRoot(routes,
            {
              enableTracing: false,
              useHash: true,
              initialNavigation: isInIframe() ? 'disabled' : undefined // <-THIS
            })],
          exports: [RouterModule]
        })
        export class AppRoutingModule {
        }
        
        export function isInIframe() {
          return window !== window.parent && !window.opener;
        }
        

        我还必须将我的登录重定向方法包装在一个 try catch 块中:

        login(loginName: string, password: string) {
              try {
                this.authService.loginRedirect();
              }
              catch(error) {
                console.log("oh no, there's an error", error);
              }
        }
        

        【讨论】:

          猜你喜欢
          • 2018-03-30
          • 2018-06-17
          • 2023-04-02
          • 2022-01-04
          • 1970-01-01
          • 2013-11-14
          • 1970-01-01
          • 2022-01-08
          • 2020-10-12
          相关资源
          最近更新 更多