angular-auth-oidc-client
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
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!
Is there any progress on this?
@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 },
];
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
I have solved my issue by switching from my AuthGaurd to using AutoLoginPartialRoutesGuard
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.
Closing as there hasn't been any response from the issue author. Please re-open if you are still seeing problems here.
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?
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.