angularwso2openid-connectidentityserver3wso2-identity-server

iframe session issue in OIDC client


I'm using OIDC Client and WSO2 API Manager 3.2.0 in my angular application for authentication. Everything works fine until I hit log out.

First, I log into the application from one tab and then duplicate that tab after a successful login. After that, when I log out from one tab, other tabs also should be logged out, but it does not happen. I have created an iframe and constantly check the session as below.

.ts file:

  baseUrl = new URL(window.location.href);
  callbackURI = this.baseUrl.origin + '/slate/dashboard';

  checkSessionURL = this.sanitizer.bypassSecurityTrustResourceUrl('https://localhost:9443/oidc/checksession' + '?client_id='
            + localStorage.getItem('client_id') + '&redirect_uri=' + this.callbackURI);

  constructor(private sanitizer: DomSanitizer, private authService: AuthService) {
  }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    if (this.authService.isLoggedUser()) {
      this.checkSession();
    }
  }

  isIFrame = (input: HTMLElement | null): input is HTMLIFrameElement =>
    input !== null && input.tagName === 'IFRAME'

  /**
   * Invoke check session OIDC endpoint.
   */
  checkSession(): void {
    setInterval(() => {
      const msg = localStorage.getItem('client_id') + ' ' + localStorage.getItem('sessionState');
      const frame = document.getElementById('iframeOP');
      if (this.isIFrame(frame) && frame.contentWindow) {
        frame.contentWindow.postMessage(msg, 'https://localhost:9443/oidc/checksession');
      }
    }, 3000);
  }

.HTML file:

<iframe
  title='iframeOP'
  id='iframeOP'
  [src]="checkSessionURL"
></iframe>

After refreshing the duplicate tab, I'm getting this.

https://localhost:9443/authenticationendpoint/oauth2_error.do?oauthErrorCode=access_denied&oauthErrorMsg=Error+occurred+while+extracting+data+from+id+token.

But, the log out in duplicated tabs should happen automatically. I appreciate if anyone could help.


Solution

  • You need to share logout event (and invoke logout function) between tabs. Suggested implementation: your SPA (each tab) needs to watch an external-logout boolean setting in local storage, using the browser Storage API (reference). More modern implementation may use Broadcast Channel API to broadcast logout event between tabs.