angular-auth-oidc-client icon indicating copy to clipboard operation
angular-auth-oidc-client copied to clipboard

[Bug]: All paths with a query string including 'code' or 'state' are being intercepted by angular-auth-oidc-client

Open ZeSzymi opened this issue 3 years ago • 5 comments

Hi This is a follow up to issue: #1049

Basically I am trying to update library to newest version and there was an issue of OIDC-client intercepting the url with query params: code or state. But I have found a workaround which was providing my own url to OidcSecurityService.CheckAuth(url).

But now you have changed the library and code looks like that

  checkAuth(configuration: OpenIdConfiguration, allConfigs: OpenIdConfiguration[], url?: string): Observable<LoginResponse> {
    if (this.currentUrlService.currentUrlHasStateParam()) {
      const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl();
      const config = this.getConfigurationWithUrlState([configuration], stateParamFromUrl);

      if (!config) {
        return throwError(() => new Error(`could not find matching config for state ${stateParamFromUrl}`));
      }

      return this.checkAuthWithConfig(config, allConfigs, url);
    }

    return this.checkAuthWithConfig(configuration, allConfigs, url);
  }

And this particular method this.currentUrlService.currentUrlHasStateParam() is not taking into consideration provided url and takes url from:

  getCurrentUrl(): string {
    return this.doc.defaultView.location.toString();
  }

And then takes state which is totally not related with login flow and throws an error

return throwError(() => new Error(`could not find matching config for state ${stateParamFromUrl}`));

It is a bad design from the start to chech every route for query parameters state and code but that's not the issue here. Could you change it so there is posibility for getStateParamFromCurrentUrl() to use url? :string as a param and then based on if it's null or not return state?

Something like

  currentUrlHasStateParam(url?: string): boolean {
    return !!this.getStateParamFromCurrentUrl(url);
  }

  getStateParamFromCurrentUrl(url?: string): string {
    const currentUrl = url ?? this.getCurrentUrl();
    const parsedUrl = new URL(currentUrl);
    const urlParams = new URLSearchParams(parsedUrl.search);
    const stateFromUrl = urlParams.get('state');

    return stateFromUrl;
  }

Regards Thank you for your work!

ZeSzymi avatar Jan 12 '22 15:01 ZeSzymi

Is there any progress on this?

charsleysa avatar May 25 '22 05:05 charsleysa

@ZeSzymi @charsleysa, we are suffering this issue too, not sure if that's an issue of this library or Angular (v13 in my project), but I think I figured out the root cause, hope it helps.

With the routing example below, if the user is hitting the root website URL like https://contoso.com/ and the authentication process completed, then as the relative redirect is used in redirectTo: 'home', Angular will route this request and forward the query strings, the final URL will be something like this https://contoso.com/home?code=[value]&scope=[value]&state=[value]&session_state=[value], then as the page URL contains the state parameter, this library will validate it again when the function CheckAuthService.checkAuth is called, however, the authStateControl stored in Session Storage has been cleared in previous authentication process, so the validation will fail with the error could not find matching config for state xxx.

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'home' },
  { path: 'home', component: HomeComponent },
  { path: 'secondary', component: SecondaryComponent },
];

As the fix, I have to use absolute redirect redirectTo: '/home', then Angular wouldn't forward the query strings and this issue go away. But if the error is still there, additionally you might need to read this issue #1318 and set historyCleanupOff: false in the OpenIdConfiguration.

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: '/home' },
  { path: 'home', component: HomeComponent },
  { path: 'secondary', component: SecondaryComponent },
];

alexchx avatar May 26 '22 14:05 alexchx

Unfortunately, I'm in this boat as well. Interestingly, I am unable to get it working even with the suggested redirectTo changes and historyCleanupOff: false

nader-eloshaiker avatar Jun 19 '22 07:06 nader-eloshaiker

I have solved my issue by switching from my AuthGaurd to using AutoLoginPartialRoutesGuard

nader-eloshaiker avatar Jun 19 '22 12:06 nader-eloshaiker

Could the others fix the issue with the given guard as well? I do not see a way to figure out if a parameter called "state" or "code" is from the url of the sts-redirect or inside the client's app.

FabianGosebrink avatar Aug 12 '22 17:08 FabianGosebrink

Closing as there hasn't been any response from the issue author. Please re-open if you are still seeing problems here.

FabianGosebrink avatar Dec 08 '22 13:12 FabianGosebrink

Hi, I wanted to reopen this issue #1349, because i still can't find solutions to the error "Error: could not find matching config for state ######". Have there been any new solutions found?

SebastienAgnez avatar Jan 02 '23 16:01 SebastienAgnez

I believe I found another possible solution. I received this error also but because of nature of my app i decided to implement OAuth2 with PKCE manually. And after this i received more or less the same problem -> it was stated on the first run of the app that states are not the same. The nature of this problem was security storage from which as I understand angular-auth-oidc-client also benefits.

So it appears that in the beginning my app runs on http://localhost:8100/ but after authorization i am redirect to http://127.0.0.1:8100. Security storage was setted twice for localhost and 127.0.0.1. As easy to understand when we are redirected we are no longer able to read a state from localhost storage so we get an error "states are not the same". If we click log in again we already are in http://127.0.0.1:8100 so state will be written and read form the same storage so everything will work.

piotradamczyk89 avatar Aug 08 '23 08:08 piotradamczyk89