0
votes

I am trying to refresh the access token silently in my Angular SPA. The authentication against the ADFS is completed. it's working fine the configuration is given below:

oauthService.configure({
      redirectUri:
        window.location.origin + '/login',
      requireHttps: true,
      scope: 'openid profile email',
      responseType: 'id_token token',
      oidc: true,
      clientId: environment.adfsClientId,
      loginUrl: environment.adfsUrl + '/oauth2/authorize',
      issuer: environment.adfsUrl,
      logoutUrl:
        environment.adfsUrl +
        '/ls/?wa=wsignoutcleanup1.0&wreply=' +
        location.protocol +
        '//' +
        location.hostname + '/login',
      postLogoutRedirectUri:
        window.location.origin + '/login',
    });

    this.oauthService.tokenValidationHandler = new JwksValidationHandler();
    this.oauthService.setStorage(localStorage);
    this.oauthService.timeoutFactor = 0.03; // for faster testing
    this.oauthService.silentRefreshRedirectUri = window.location.origin + '/search';
    this.oauthService.setupAutomaticSilentRefresh();

For refreshing the token, the iframe is getting added to the current page. everything looks good. and I've added the following code to the index.html file.

  <script>
    parent.postMessage(location.hash, location.origin);
  </script>

This event is getting captured in the angular-oauth2-oidc.js in silentRefreshPostMessageEventListener. But the problem is the message I am getting in that lister is,

MSIS9621: Unable to handle the OAuth authorization request without getting user input.

the src tag value that getting generated in the iframe is as given below,

https://[adfs domain]/adfs/oauth2/authorize/?response_type=id_token%20token&client_id=af0e4d79-ae9d-4fda-86b3-265d1e86a61e&state=UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsearch&scope=openid%20profile%20email&nonce=UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&prompt=none

if I open this URL in a new tab, I am getting a new access token in the Uri.

can anyone tell me what I am doing wrong here?

UPDATE

Thanks, Gary Archer for the answer.

I made the changes in the ADFS by executing this code in PowerShell,

Set-AdfsResponseHeaders -RemoveHeaders "X-Frame-Options"

nothing changed. Then i set the below command to fix that problem.

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "frame-ancestors < sources >"

1

1 Answers

2
votes

Looks like ADFS is blocking iframe requests and sending an X-Frame-Oprions=DENY header. According to this post it is solvable in ADFS 2019.

One option that might work is to use refresh tokens instead, but that is not recommended for production SPAs in 2021, since a refresh token should not be stored anywhere in the browser.

It is worth bearing in mind that silent iframe based renewal is not really recommended in 2021 either, since an attacker can potentially exploit it on their own hidden iframe and get tokens.

The preferred option in 2021 is for a Back End for Front End approach, where an API deals with token renewal for the SPA.

AZURE AD API DRIVEN APPROACH

The way to proceed would be to plug in an API and point it to Azure AD endpoints. This would keep tokens out of the browser, where only SameSite cookies would be used.

The following solution from Curity demonstrates this approach, and the API can be pointed to any Authorization Server. It requires some digesting though.