1

I used the angular-oauth2-oidc library to implement an oAuth authorization code fow with PKCE in my AppComponent. It works fine and I'm even able to pass in some custom query parameters that I need to change the login form that I receive from my oAuth authorization server according to the user's language and country.

But I was only able to make this work, when I hard code the language and the country into the customQueryParams of my oAuthService. So this code works:

export class AppComponent {

 constructor(private oauthService: OAuthService) { }

  ngOnInit() {

let authConfig: AuthConfig = {
  issuer: 'https://myIssuerURL.com',
  redirectUri: 'https://myRedirectURL.com',
  clientId: environment.myClientId,
  scope: 'openid',
  responseType: 'code',
  showDebugInformation: true,  
};

this.oauthService.customQueryParams = {          // this is the important part. I want to change the country and locale dynamically
  'country': 'DE',
  'locale': 'de_DE'
};

this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.setupAutomaticSilentRefresh();
this.oauthService.loadDiscoveryDocumentAndTryLogin();

this.oauthService.events.subscribe(e => {
  console.log("OAuthEvent: ", e)
  if (e.type === "token_received") {
   
    // This works, I get the access token and the IdentityClaims.
    this.logger.log("The IdentityClaims are: ", this.oauthService.getIdentityClaims())
    this.logger.log("The accessToken: ", this.oauthService.getAccessToken())
    
  }
  (e instanceof OAuthErrorEvent) ? this.logger.error(e) : this.logger.warn(e);
});
}

But I need to dynamically retrieve the country and language from my URL, then pass them into the oAuthService and then init the Code Flow. But now when I want to get these params from the URL I have a problem. The AppComponent is a non-routing component so I can't simply access the query params in the URL with paramMap.snapshot. So I tried following:

export class AppComponent {

constructor(private oauthService: OAuthService, 
  private route: ActivatedRoute, 
  private router: Router) { }

ngOnInit() {

 this.router.events
      .pipe(
    filter(e => (e instanceof ActivationEnd) && (Object.keys(e.snapshot.params).length > 0)),
    map(e => e instanceof ActivationEnd ? e.snapshot.params : {})
  )
  .subscribe(params => {
  
 let authConfig: AuthConfig = {
  issuer: 'https://myIssuerURL.com',
  redirectUri: 'https://myRedirectURL.com',
  clientId: environment.myClientId,
  scope: 'openid',
  responseType: 'code',
  showDebugInformation: true,  
 };

 this.oauthService.customQueryParams = {     // this is the important part that doesn't work dynamically
  'country': params.country,
  'locale': params.locale
 };

 console.log(params.country)   // DE
 console.log(params.locale)    // de_DE

 this.oauthService.tokenValidationHandler = new JwksValidationHandler();
 this.oauthService.setupAutomaticSilentRefresh();
 this.oauthService.loadDiscoveryDocumentAndTryLogin();

 this.oauthService.events.subscribe(e => {
  // This doesn't work, I never get here.
  console.log("OAuthEvent: ", e)
  if (e.type === "token_received") {
   
    // This doesn't work, I never get here.
    this.logger.log("The IdentityClaims are: ", this.oauthService.getIdentityClaims())
    this.logger.log("The accessToken: ", this.oauthService.getAccessToken())
    
  }
  (e instanceof OAuthErrorEvent) ? this.logger.error(e) : this.logger.warn(e);
 });
}

Although this method works to retrieve the country and locale correctly from my URL (as I can see with the console.log(country) and console.log(locale) statements), I here never receive the access token or identityClaims.

I also tried to move all my oAuthService configuration into the LoginComponent, because there I can just normally access the URL params with the activatedRoute and then configure the oAuthService with the params. But this also doesn't work, I also never receive the access token or IdentityClaims. I don't understand this, is it not possible to configure the oAuthService in another component than in the AppComponent? In all examples that I found it got configured in the AppComponent, but why? Is this a must? And why is it not working when I configure it inside the subscribe part of my first approach?

Thank you very much.

bwx--2
  • 181
  • 2
  • 11
  • An issue I had with this was that the `code` parameter in the query string was not present when I navigated to a different component, as Angular had cleared it. I had to put the call to `loadDiscoveryDocumentAndTryLogin()` inside an `APP_INITIALIZER`. – PMah Jul 11 '22 at 14:42

0 Answers0