0

我已经使用 angular-oauth2-oidc API 实现了一个基本的 Oauth2/OIDC 静默刷新,并且在获取指向我的应用程序中特定区域的链接以正常工作时遇到了一些问题。

例如,应用程序为用户生成电子邮件以到达某个页面。单击该链接时,页面会呈现片刻,然后重新加载似乎来自 OAuth 请求,并且应用程序返回到初始页面。

    export class AppComponent implements OnInit {
      private authConfig: AuthConfig;
      constructor(
        private oauthService: OAuthService,
        private location: Location,
      ) {
        console.log("AppComponent:constructor");
        this.configureOAuth();
      }
    
      ngOnInit() {
      }
    
      private configureOAuth() {
        this.authConfig = {
          issuer: this.getIssuer(),
          clientId: environment.clientId,
          scope: 'openid profile email preferred_username',
          responseType: 'code',
          redirectUri: `${window.location.origin}/`,
          silentRefreshRedirectUri: `${window.location.origin}/silent-renew.html`,
          useSilentRefresh: true,
          showDebugInformation: true,
        };
    
        this.oauthService.configure(this.authConfig);
        this.oauthService.setStorage(sessionStorage);
        this.oauthService.setupAutomaticSilentRefresh();
    
        this.oauthService.loadDiscoveryDocumentAndLogin();
     }

我的 AppComponent 似乎在控制台日志中加载了两次:

Navigated to: https://localhost:44306/action/1234
AppComponent:constructor
HttpRequestInterceptor: hasValidAccessToken:  https://auth.myhost.com/.well-known/openid-configuration
HttpRequestInterceptor: hasValidAccessToken:  https://auth.myhost.com/pf/JWKS
oauth/oidc event discovery_document_loaded
oauth/oidc event discovery_document_loaded

Navigated to https://localhost:44306/?code=b5dcWoxpFnc2Z9lfaCJaVWoj-l0oEpo1AG8AAAAG&state=VGplenktRWZ3N21aNDh5UHdlSVMyMGJOVEJheDBMa0lTeU1kaGR1OTRoSy5Y

AppComponent:constructor
oauth/oidc event discovery_document_loaded
oauth/oidc event discovery_document_loaded
http-request-interceptor.service.ts:25 HttpRequestInterceptor: hasValidAccessToken:  https://auth.myhost.com/as/token.oauth2
refresh tokenResponse {access_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx4cmdXck1EVV9nN3ROSV…Hq720zdSrR4UkPwBRTmfZIE0ZbLNHYl0v-DhNHChEBrSE0-OA", id_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx4cmdXck1EVV9nN3ROSV…hynONaOjaeBKv63jKRm-m4VPC3JRysIRj0-zK4Y0C7VGdnjUA", token_type: "Bearer", expires_in: 7199}
oauth/oidc event token_received
oauth/oidc event token_refreshed

我假设我在这里遗漏了一些非常简单的东西,但是在过去 8 个小时阅读了 angular-oauth2-oidc 文档、示例和谷歌搜索想法之后,我发现我是空的。

谢谢

4

1 回答 1

1

经过一夜的睡眠并重新阅读了一些帖子后,我找到了正确的组合来使事情正常进行。

首先,在我的 RouterModule 中,我重新配置以停止初始导航:

@NgModule({
  imports: [RouterModule.forRoot(routes, { initialNavigation: false })],

在我的 RouteGuard 中,我仅在检索到令牌后才激活:

  canActivate(
    route: ActivatedRouteSnapshot, state: RouterStateSnapshot
  ) {
    let hasIdToken = this.oauthService.hasValidIdToken();
    let hasAccessToken = this.oauthService.hasValidAccessToken();
    return (hasIdToken && hasAccessToken);
  }

最重要的是,在我的 AppComponent 中,我将初始 URL 传递给 initCodeFlow 并在返回时使用它:

  constructor(
    private oauthService: OAuthService,
    private router: Router,
    private location: Location,
  ) {
    this.url = this.location.path(true);
    this.configureOAuth();
  }

  private configureOAuth() {
    this.authConfig = {
      issuer: this.getIssuer(),
      clientId: environment.clientId,
      scope: 'openid profile email preferred_username',
      responseType: 'code',
      redirectUri: `${window.location.origin}/`,
      silentRefreshRedirectUri: `${window.location.origin}/silent-renew.html`,
      useSilentRefresh: true,
    };
       
    this.oauthService.configure(this.authConfig);
    this.oauthService.setupAutomaticSilentRefresh();

    return this.oauthService.loadDiscoveryDocumentAndTryLogin().then(() => {
      if (this.oauthService.hasValidIdToken()) {
        if (this.oauthService.state) {
          this.router.navigateByUrl(decodeURIComponent(this.oauthService.state));
        }
        else {
          this.router.navigateByUrl('/');
        }
        this.isLoaded = true;
      } else {
        // init with requested URL so it can be retrieved on response from state
        this.oauthService.initCodeFlow(this.url);
      }
    });
  }
于 2020-09-01T12:38:40.763 回答