【问题标题】:Angular 8 OIDC client - maximum call stack exceeded with authorizeAngular 8 OIDC 客户端 - 超过授权的最大调用堆栈
【发布时间】:2021-07-01 23:47:21
【问题描述】:

我们使用 this oidc 客户端作为我们的 Angular 前端。

该应用程序应该在另一个应用程序的 iframe 中(不是 Angular) - 通常用户已经登录到 sts,所以我们想尝试立即授权,看看我们是否需要做“适当的”授权与否。

虽然发生了一些奇怪的事情。

我们在应用模块中使用客户端正常初始化:

export class AppModule {
  constructor(private oidcSecurityService: OidcSecurityService, private oidcConfigService: OidcConfigService) {
    this.oidcConfigService.onConfigurationLoaded.subscribe((configResult: ConfigResult) => {
    // Use the configResult to set the configurations

    const config: OpenIdConfiguration = {
      stsServer: configResult.customConfig.stsServer,
      redirect_url: configResult.customConfig.redirect_url,
      client_id: configResult.customConfig.client_id,
      response_type: 'code',
      scope: "openid profile",
      silent_renew: true,
      silent_renew_url: 'https://localhost:4200/silent-renew.html',
      log_console_debug_active: true,
    };

    this.oidcSecurityService.setupModule(config, configResult.authWellknownEndpoints);
});

 }
}

然后在应用程序组件中,我们立即尝试像这样进行授权:

import { Component } from '@angular/core';
import { OidcSecurityService } from 'angular-auth-oidc-client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(public oidcSecurityService: OidcSecurityService) { 
    if (this.oidcSecurityService.moduleSetup) {
      this.doCallbackLogicIfRequired();
  } else {
      this.oidcSecurityService.onModuleSetup.subscribe(() => {
          this.doCallbackLogicIfRequired();
      });
  }
}

ngOnInit() {
  this.oidcSecurityService.getIsModuleSetup().subscribe(() => {
    this.oidcSecurityService.getIsAuthorized().subscribe(auth => {
      if (auth === false) {
        this.oidcSecurityService.authorize();
      }
    })
  })
}

ngOnDestroy(): void {}

login() {
  this.oidcSecurityService.authorize();
}

logout() {
  this.oidcSecurityService.logoff();
}

private doCallbackLogicIfRequired() {
  this.oidcSecurityService.authorizedCallbackWithCode(window.location.toString());
}
}

这会导致授权触发,返回到应用程序,该应用程序在 oidcSecurityService.getIsAuthorized() 发出任何值之前再次尝试授权,这会导致无限循环,从而导致超出最大调用堆栈。

但是,如果我们只是在应用组件中引入较长的延迟,它就会开始像您期望的那样运行:

ngOnInit() {
  this.oidcSecurityService.getIsModuleSetup().subscribe(() => {
    this.oidcSecurityService.getIsAuthorized().subscribe(auth => {
      if (auth === false) {
         setTimeout(() => {
           this.oidcSecurityService.authorize();
         }, 10000);
      }
    })
  })
}

当然我们会看到与以前相同的行为,只是延迟 10 秒,但我们没有。 为什么? 为什么超时可以解决问题?我们是不是走错路了?

【问题讨论】:

    标签: angular observable openid-connect


    【解决方案1】:

    使用 distinctUntilChanged 管道解决了这个问题,尽管我可以看到在控制台中,来自库的调试日志的 getIsAuthorized 似乎连续发出两个错误 - 我想这就是症结所在,不要知道这是否是预期的行为。

    this.oidcSecurityService.getIsAuthorized().pipe(distinctUntilChanged()).subscribe(auth => {
          if (auth === false) {
               this.oidcSecurityService.authorize();
          }
        });
    

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 2020-08-22
      • 2018-12-08
      • 1970-01-01
      • 2020-01-05
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      相关资源
      最近更新 更多