I am using Symfony 6 and PHP League OAuth package.
I have built a custom authenticator to log in a user - I am able to authenticate a user just fine.
However, I am having trouble setting protection for the other routes of my application, and can still access them when not authenticated.
Custom Authenticator:
public function authenticate(Request $request): Passport
{
$session = $request->getSession();
$provider = new Google([
'clientId' => 'myclientid',
'clientSecret' => 'myclientsecret',
'redirectUri' => 'mycallback',
]);
if (!empty($request->query->get('error'))) {
// I do a bunch of error checks in here
} else {
// We got an access token, let's now get the owner details
$googleUser = $provider->getResourceOwner($token);
$user = $this->userRepository->updateOrCreate([
'email' => $googleUser->getEmail(),
'name' => $googleUser->getName(),
'google_id' => $googleUser->getId(),
'google_token' => $token->getToken(),
]);
return new SelfValidatingPassport(
new UserBadge($token->getToken())
);
}
...
In my security.yaml
providers:
user_provider:
entity:
class: App\Entity\User
property: google_token
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
public:
pattern: ^/(|connect/google)/
security: false
google_authenticator:
custom_authenticator: App\Security\GoogleAuthenticator
logout:
path: app_logout
access_control:
- { path: ^/, roles: PUBLIC_ACCESS }
- { path: /connect/google, roles: PUBLIC_ACCESS }
- { path: /dashboard, roles: IS_AUTHENTICATED_FULLY }
What I am trying to prove here, is that I shouldn't be able to access /dashboard
unless I am authenticated, but it's letting me access that page regardless. When I am logged in, I can dump out the authenticated user from the session, so I know I can authenticate users.
/dashboard
route?Thanks.
Symfony stops its checks at the first "validated" rule:
For each incoming request, Symfony checks each access_control entry to find one that matches the current request. As soon as it finds a matching access_control entry, it stops - only the first matching access_control is used to enforce access.
Reference: https://symfony.com/doc/current/security/access_control.html
In your case, it matches everytime the first rule { path: ^/, roles: PUBLIC_ACCESS }
.
To solve your issue, move { path: ^/, roles: PUBLIC_ACCESS }
at the end of your configuration:
access_control:
- { path: /connect/google, roles: PUBLIC_ACCESS }
- { path: /dashboard, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/, roles: PUBLIC_ACCESS }