-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Symfony version(s) affected
7.3.1
Description
In my project, I'm currently using the HWIOAuthBundle bundle in order to implement sign in via google.
The redirect uri configured in Google console needs to be http(s)://localhost/.... or a domain with a valid suffix like .com or .io. Using Traefik, I usually configure my projects with domains like app1.docker.localhost, but Google doesn't allow it, so I switched and now I try to use path prefix reverse proxying like http://localhost/app1.
I configured Traefik to add the needed X-Forwarded-* headers and configured my Symfony app after the documentation so it works properly.
In the other hand, the HWIOAuthBundle uses Symfony\Component\Security\Http\HttpUtils in order to create redirect uri and to process OAuth workflow. The OAuthAuthenticator from the bundle contains the lines below:
public function authenticate(Request $request): Passport
{
// $checkPath can be either a path, or a route name
[$resourceOwner, $checkPath] = $this->resourceOwnerMap->getResourceOwnerByRequest($request);
//...
$accessToken = $resourceOwner->getAccessToken(
$request,
$this->httpUtils->createRequest($request, $checkPath)->getUri()
);
//...
}And there is the bug. With the following context:
- Traefik redirects
http://localhost/my-appto my symfony app /my-appis configured asX-Forwarded-Prefix
We have the following results:
$request->getUri()=>http://localhost/my-app/$this->httpUtils->createRequest($request, '/')->getUri()=>http://localhost/my-app/my-app/
After digging, the main difference I found is that the REQUEST_URI attribute from the request's server bag has changed from / to /my-app/ between the initial $request object and the one created by $this->httpUtils->createRequest($request, '/')
In addition, this also impacts every authenticator using HttpUtils::createRequest(), like the FormLoginAuthenticator when theuse_forward option is enabled.
How to reproduce
Configure a local reverse proxy like Traefik.
With docker compose:
services:
my-app:
#...
environment:
SYMFONY_TRUSTED_PROXIES: "PRIVATE_SUBNETS"
SYMFONY_TRUSTED_HEADERS: "x-forwarded-for,x-forwarded-host,x-forwarded-proto,x-forwarded-port,x-forwarded-prefix"
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=PathPrefix(`/my-app`)"
- "traefik.http.routers.my-app.entrypoints=web"
- "traefik.http.middlewares.app-stripprefix.stripprefix.prefixes=/my-app"
- "traefik.http.routers.my-app.middlewares=app-stripprefix"Create a simple controller and generate the uris:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\HttpUtils;
class IndexController extends AbstractController
{
#[Route('/')]
public function test(Request $request, HttpUtils $httpUtils)
{
$uri = $request->getUri();
$newRequest = $httpUtils->createRequest($request, '/');
$newUri = $newRequest->getUri();
dd($uri, $newUri);
}Possible Solution
No response
Additional Context
No response