OidcClient.readSigninResponseState: No matching state found in storage - oidc-client-js (Angular)

Viewed 10334

I am using oidc-client library for integrating with Azure AD in my Angular(9) application. signinRedirect() & signinSilent() functions are working as expected. But for signinPopup(), it is getting the access token successfully in the browser url fragment but it throws error mentioned below:

app.component.ts:83 Error: No matching state found in storage at oidc-client.min.js:1

Surprisingly, in signin-callback.html, when I pass the response_type as query var userManager = new Oidc.UserManager({response_mode: "query"});, sign in pop up works successfully But sign in redirect fails complaining that

Error: No state in response

I have followed this article initially.

Here is my service code:

import { Injectable } from '@angular/core';
import { UserManager, UserManagerSettings, User } from 'oidc-client';

import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private userManager: UserManager;

  constructor() {
    this.instantiate();
  }

  private instantiate() {
   this.userManager = new UserManager(this.getOidcSettings());
  }

  public async signinRedirect(): Promise<any> {
    return this.userManager.signinRedirect();
  }

  public async signinSilent(): Promise<User> {
    return this.userManager.signinSilent();
  }

  public async signinPopup(): Promise<User> {
    return this.userManager.signinPopup();
  }

  public async signoutRedirect(): Promise<any> {
    this.userManager.signoutRedirect();
    this.userManager.clearStaleState();
  }

OIDC Settings:

const userManagerSettings: UserManagerSettings = {
      client_id: 'my clientid',
      authority: 'my authority',

      redirect_uri: 'http://localhost:4200/assets/oidc/signin-callback.html',
      silent_redirect_uri: 'http://localhost:4200/assets/oidc/silent-refresh-callback.html',
      post_logout_redirect_uri: 'https://localhost:4200/',

      response_type: 'token',
      response_mode: 'fragment',
      scope: 'my api scope',

      loadUserInfo:false
    };

signin-callback.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.10.1/oidc-client.min.js"></script>
    <script>
      var userManager = new Oidc.UserManager();

      userManager.signinRedirectCallback().then(
        (user) => {
          alert('signin redirect successful.');
          window.history.replaceState(
            {},
            window.document.title,
            window.location.origin
          );
          window.location = '/';
        },
        (err) => {
          alert('Error caught in signinRedirectCallback()');
          console.log('Error caught in signinRedirectCallback().');
          console.error(err);
        }
      );

      userManager.signinPopupCallback().then(
        (user) => {
          alert('signin pop up successful.');
          window.history.replaceState(
            {},
            window.document.title,
            window.location.origin
          );
          window.location = '/';
        },
        (err) => {
          alert('Error caught in signinPopupCallback()');
          console.log('Error caught in signinPopupCallback().');
          console.error(err);
        }
      );
    </script>
  </head>
  <body></body>
</html>

silent-refresh-callback.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.10.1/oidc-client.min.js"></script>
    <script>
      var userManager = new Oidc.UserManager();
      userManager.signinSilentCallback().catch((err) => {
        console.log('Error caught in signinSilentCallback().');
        console.error(err);
      });
    </script>
  </head>
  <body></body>
</html>
2 Answers

We had a similar issue where this error was appearing intermittently for a subset of users. We've learned of two specific reasons so far why this has been happening:

  1. Some users with system clocks set more than 5 minutes away from the current actual time (the clockSkew defaults to 5 minutes in oidc-client-js)

  2. Some users were sharing and re-using the unique generated login URLs w/ security parameters generated by Identity Server. It was possible to login with identity server, but the security vars like nonce didn't match (and ended up throwing the 'No matching state found in storage' error in the oidc-signin callback)

It happened to me as well, for my case we configured Identity Server site with https and I am trying to access the bookmark URL which was old and it was stored as http.

This caused me the same OIDC issue. After reverting the URL back to https everything worked for me.

Related