4

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>
  • 1
    Clearing my browser cache (From Settings) fixed the issue for me. In some cases, I had to manually go into the Application tab and once you are at the homepage of your site, clear the session and state storage. That fixed the issue for me. – Pranav Jituri Jun 09 '20 at 20:09
  • Did you find a solution/fix for this? – ux.engineer Oct 06 '20 at 14:16

1 Answers1

0

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)

amlutz160
  • 330
  • 3
  • 15
  • 1
    How did you solve number 2? Do you have any recommendations on how to prevent that from happening? – Mariano Soto May 18 '21 at 18:29
  • @MarianoSoto unfortunately we haven't addressed #2 as it was de-prioritized. Once we dig into it, we may look at ways to tighten requirements w/ identity server so that it can reject a re-used login link for example. (Eg figure out a way to reject stale security params in the url and force a redirect to restart the login flow) – amlutz160 May 24 '21 at 15:21