1
votes

For a project I`m using this library: angular-oauth2-oidc for Support in OAuth 2 and OpenId Connect (OIDC) in Angular.

I have everything set up and all is working fine.

MainComponent File:

export class MainComponent implements OnInit {

  constructor() {
    this.configureSSO();
  }

  configureSSO() {
    this.oAuthService.configure(authConfig);
    this.oAuthService.tokenValidationHandler = new JwksValidationHandler();

    this.oAuthService.loadDiscoveryDocumentAndTryLogin().then(() => {
      // the lib received the access_token as well as the id_token, if it was requested. 
      // If there is an id_token, the lib validated it.
      // DO STUFF WITH TOKEN HERE
    });
  }
}

authConfig File:

import {AuthConfig} from 'angular-oauth2-oidc';

export const authConfig: AuthConfig = { /...SOME CONFIG HERE .../ }

AuthGuard File:

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private router: Router, private oAuthService: OAuthService) {
  }

  canActivate(): boolean {
    if(this.oAuthService.hasValidIdToken()){
      return true;
    }
    return false;
  }
}

After a successful Login on the OIDC Providers Site, I can see the access_token being saved in the Session Storage of my local Browser:

enter image description here

This all works perfectly, BUT, if I now proceed to change the token in the Session Storage, I'm still able to get into my protected routes. Although the access_token was altered. Same thing when id_token is changed.

--> The AuthGuard still lets me go to my protected Routes.

Can anybody enlighten me on how this would be possible?

I'm not able to find anything about how this is handled internally in the docs Documentation angular-oauth2-oidc

I'm quite sure it is NOT an Implementation Fault, but rather that the library saves the token somewhere internally, and uses the unaltered token instead, as everything else works as expected perfectly.

But WHY save the token in the Session Storage anyway if it is not (really) used?!?

More:

If I actually delete the whole token from the storage, all blocked Routes are actually blocked - which is good! Same thing happens when I alter the Expiration Time (exp) inside the JWT to something before the actual time. So these two checks are actually working fine, but when changing access_token or id_token the AuthGuard still gets a valid Token... (maybe from inside the lib?!?)

I think there's something I don't understand about JWT in general, and why they are even saved in local/session Storage, or why the change to them does have no effect...

Any answers are greatly appreciated.

1

1 Answers

0
votes

In the basic scenario, the library will assume that every bit of JavaScript "plays nice" with session storage, effectively treating it as private storage for the library. If you want to clear login so that the route guards can pick it up, you should not pry into storage yourself, but instead call logout on the service. That will effectively clear storage.

Basically, if you delete stuff from sessionStorage (or localStorage if you'd be using that) that "belongs" to the library, you're breaking it.

Your guards are an application concern, and they should be able to trust the library (which in turn should be able to trust storage), to determine what would happen if the library considers a user "logged in".

The library itself normally does not use tokens at all, unless you tell it to. The most common case is to provide a module config to ensure the access_token is being sent along to your API. E.g.:

{ 
  provide: OAuthModuleConfig,
  useValue: {
    resourceServer: {
      allowedUrls: ['https://example.org/my-api'],
      sendAccessToken: true
    }
  }
}

Now, if you want to "protect" against other code meddling with the storage for the library, you can provide your own implementation of OAuthStorage, e.g.:

function storageFactory() {
  const privateStore = {};

  return {
    getItem(key) { return privateStore[key]; }
    removeItem(key) { delete privateStore[key]; }
    setItem(key, data) { privateStore[key] = data; }
  };
}
{ provide: OAuthStorage, useFactory: storageFactory }

I use a similar method to provide localStorage instead of sessionStorage in my sample repo.