Open nitrique opened 2 years ago
I'm running into this same issue, using Symfony 5.4 and the new authentication manager.
I'm guessing it has something to do with the recent changes to session management, but not sure. Open to suggestions.
In the end, the issue was an invalid secret. The 404 threw me off.
I'm facing the same issue with Google login.
Symfony 5.4 with new authenticator manager
Session key "knpu.oauth2_client_state" is not found, so "expectedState" is null. This condition is resolved to "true" and exception is triggered. https://github.com/knpuniversity/oauth2-client-bundle/blob/e7e0cc5d5aa3b04210c5c56ada69a7a8dc858abc/src/Client/OAuth2Client.php#L98-L100
Hey, maube it's too late, but i had that error too, because i went one page back, instead of the origin call. (hope you understand what i mean)
Not too late, problem is not solved and this package looks to be not actively maintained. We have planed to implement it by ourself.
Could anyone create a PR that would fix this issue? I'd be happy to review it
I have the same problem with Safari 15.1. The session with the state key is set in the redirect () method in /Client/OAuth2Client.php, while after redirecting in the getAccessToken method, the session with the key self :: OAUTH2_SESSION_STATE_KEY is missing.
It's weird that everything works fine in Chrome. Anyone can help?
One more with the same issue I created my server following this https://davegebler.com/post/php/build-oauth2-server-php-symfony#what-we'll-be-building and then another app with this bundle. The user is logged in on the oauth server but when it comes back and try to find this session variable is null
I'm facing the same issue with Google login.
Symfony 5.4 with new authenticator manager
Session key "knpu.oauth2_client_state" is not found, so "expectedState" is null. This condition is resolved to "true" and exception is triggered.
did you found a solution?
hey, sorry for my late answer ! I don t really remind all i did, but i had to follow a tutoriel for Symfony 6, there has been somes changes, even i run a symfony 5.4. I remember i had to change some specific stuff in the bundle, the auth thing is not the same anymore. It was that tutoriel https://www.dev-web.io/2022/03/07/symfony-6-sauthentifier-avec-google-facebook-github/ and i think it's the extends i had to change but not only in my controller I really hope, it helps
Hi,
the problem is still not solved... I already tried to do this in my construct but it still doesn't work
For me the error
Invalid state parameter passed in callback URL.
Was simply due to having multiple PHP servers (via Kubernetes) serving users. If you got unlucky (highly likely) then you get a different server with different sessions.
From the user perspective the browser will show the browser received a cookie for a brief subsecond, then it is immediately purged.
Switching to an alternative session management strategy worked. Notably from the linked page, this line is particularly relevant:
Symfony stores sessions in files by default. If your application is served by multiple servers, you'll need to use a database instead to make sessions work across different servers.
gl
I had invalid state pop up recently, but that's because I had changed my cookie_samesite
from lax
to strict
.. But apparently Google login doesn't like strict
, so I changed it back to lax
.
Ok I solved this, here is what I had:
public function supports(Request $request): ?bool {
return $request->attributes->get("_route") === "oauth_connect";
}
and it should be
public function supports(Request $request): ?bool {
return $request->attributes->get("_route") === "oauth_callback";
}
You should start authenticating once the user reaches back to your page, not while sending them to the OAuth provider's page.
The reason no state is set is because you really don't have a state. This is also documented somewhere in the middle of the README.
Hope this helps!!!
Ok I solved this, here is what I had:
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_connect"; }
and it should be
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_callback"; }
You should start authenticating once the user reaches back to your page, not while sending them to the OAuth provider's page.
The reason no state is set is because you really don't have a state. This is also documented somewhere in the middle of the README.
Hope this helps!!!
Can you help me understand this better?
This is what I've
public function supports(Request $request): ?bool
{
return $request->attributes->get('_route') === 'connect_google_check';
}
I am facing this issue where a lot of users cannot login and getting Invalid State error. Mostly on iphone/mac
Ok I solved this, here is what I had:
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_connect"; }
and it should be
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_callback"; }
You should start authenticating once the user reaches back to your page, not while sending them to the OAuth provider's page. The reason no state is set is because you really don't have a state. This is also documented somewhere in the middle of the README. Hope this helps!!!
Can you help me understand this better?
This is what I've
public function supports(Request $request): ?bool { return $request->attributes->get('_route') === 'connect_google_check'; }
I am facing this issue where a lot of users cannot login and getting Invalid State error. Mostly on iphone/mac
Ok, to understand why you are getting the error you need to understand OAUTH in general and also how symfony handles authentication using authenticators. Disclaimer, I am using Symfony 5.4.
As you can see our server has 2 points of interaction,
/oauth/connect/{provider}
/oauth/connect/{provider}/callback
Now, here is where things get weird with symfony and its authenticators: The callback route should be intercepted by the authenticator (think of it as some kind of middleware) to handle the login logic.
/**
* Link to this controller to start the "connect" process
*
* @Route("/oauth/connect/{provider}", name="oauth_connect")
*/
public function startOauthFlow(
Request $request,
ClientRegistry $clientRegistry
) {
$provider = $request->get("provider");
try {
return $clientRegistry
->getClient($provider)
->redirect(["openid", "public_profile", "email"], []);
} catch (Exception $e) {
$this->addFlash("danger", self::START_ERROR . $e->getMessage());
return $this->redirectToRoute("app_login");
}
}
/**
* After going to the provider, you're redirected back here
* because this is the "redirect_route" you configured
* in config/packages/knpu_oauth2_client.yaml
*
* @Route("/oauth/connect/{provider}/callback", name="oauth_callback", schemes={"https"})
*/
public function callback(Request $request, ClientRegistry $clientRegistry) {
// this can be empty, it will get intercepted by the authenticator
return;
}
The callback gets intercepted by this function in your authenticator:
public function authenticate(Request $request): PassportInterface {
$provider = $request->get("provider");
$client = $this->clientRegistry->getClient($provider);
$accessToken = $this->fetchAccessToken($client);
$handler = new OauthAuthentication(
$this->clientRegistry,
$this->entityManager,
$accessToken
);
return $handler->Authenticate($request);
}
after that the onSuccess
Logic
The last thing you need for this to work out is to add your authenticator to your main
firewall and it should work.
firewalls:
main:
custom_authenticator: App\Security\Authenticators\OAuthAuthenticator
as for support, it's only for symfony to know which authenticator it will use. so if you just keep you oauth_callback
route you should be fine.
public function supports(Request $request): ?bool {
return $request->attributes->get("_route") == "oauth_callback";
}
I hope this helps out!
in my case, the problem was I pressed the back button on the browser
Ok I solved this, here is what I had:
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_connect"; }
and it should be
public function supports(Request $request): ?bool { return $request->attributes->get("_route") === "oauth_callback"; }
You should start authenticating once the user reaches back to your page, not while sending them to the OAuth provider's page. The reason no state is set is because you really don't have a state. This is also documented somewhere in the middle of the README. Hope this helps!!!
Can you help me understand this better? This is what I've
public function supports(Request $request): ?bool { return $request->attributes->get('_route') === 'connect_google_check'; }
I am facing this issue where a lot of users cannot login and getting Invalid State error. Mostly on iphone/mac
Ok, to understand why you are getting the error you need to understand OAUTH in general and also how symfony handles authentication using authenticators. Disclaimer, I am using Symfony 5.4.
Simplified oauth flow
As you can see our server has 2 points of interaction,
- handling the initialization of the flow
/oauth/connect/{provider}
- having a callback once the provider is done processing the user's log in request
/oauth/connect/{provider}/callback
Now, here is where things get weird with symfony and its authenticators: The callback route should be intercepted by the authenticator (think of it as some kind of middleware) to handle the login logic.
Init
/** * Link to this controller to start the "connect" process * * @Route("/oauth/connect/{provider}", name="oauth_connect") */ public function startOauthFlow( Request $request, ClientRegistry $clientRegistry ) { $provider = $request->get("provider"); try { return $clientRegistry ->getClient($provider) ->redirect(["openid", "public_profile", "email"], []); } catch (Exception $e) { $this->addFlash("danger", self::START_ERROR . $e->getMessage()); return $this->redirectToRoute("app_login"); } }
Callback
/** * After going to the provider, you're redirected back here * because this is the "redirect_route" you configured * in config/packages/knpu_oauth2_client.yaml * * @Route("/oauth/connect/{provider}/callback", name="oauth_callback", schemes={"https"}) */ public function callback(Request $request, ClientRegistry $clientRegistry) { // this can be empty, it will get intercepted by the authenticator return; }
The callback gets intercepted by this function in your authenticator:
public function authenticate(Request $request): PassportInterface { $provider = $request->get("provider"); $client = $this->clientRegistry->getClient($provider); $accessToken = $this->fetchAccessToken($client); $handler = new OauthAuthentication( $this->clientRegistry, $this->entityManager, $accessToken ); return $handler->Authenticate($request); }
after that the
onSuccess
LogicThe last thing you need for this to work out is to add your authenticator to your
main
firewall and it should work.firewalls: main: custom_authenticator: App\Security\Authenticators\OAuthAuthenticator
as for support, it's only for symfony to know which authenticator it will use. so if you just keep you
oauth_callback
route you should be fine.public function supports(Request $request): ?bool { return $request->attributes->get("_route") == "oauth_callback"; }
I hope this helps out!
Hi Thanks for the explanation. I believe I have the proper configuration. I am using Symfony 7.1 and this often gets Invalid State error. I even tried to disable the state option in the configuration.
My clients were frustrated. I finally resolved this yesterday by switching to HWIOAuthBundle and I no longer get the issue. This is clearly a bug in the knpuniversity eco system, unfortunately I don't know how to troubleshoot this. I posted my configuration in the thephpleague repo for the google auth, but it wasn't helpful as well. https://github.com/thephpleague/oauth2-google/issues/124
Thanks for posting this. I also believe that https://github.com/knpuniversity/oauth2-client-bundle/issues/436 is a bug in the library, but it's related to something deep in the cache or nginx configuration or something related to http v https. While I don't think my issue is related to yours, I guess I should consider your solution (switching to HWIOAuthBundle).
Hi,
Using this module with Keycloak client, I randomly get the error "Invalid state passed in parameters callback url", in both Firefox and Brave (chromium).
Using Safari with localhost (without https), this error is shown every time and I cannot access to my interface. I've put some breakpoint in this bundle, and found out that the cookie is cleared between navigations.
It seems that Safari try to protect navigation and tracking when using redirect from another site, which is indeed problematic when using oauth2. Note that the cookie is set in "lax" mode. But in reality it clear the "phpsessid" cookie :( .
Do some of you guys already had this matter and found out a solution ?
Thanks, Best regards.
Nicolas