Musaffar Patel
Musaffar Patel

Reputation: 1372

Public Access with Symfony's AbstractAuthenticator

I'm exploring the new system for User Authentication using the new AbstractAuthenticator class in my symfony 5 project.

My symfony app will contain a mix of routes, some will only be accessible to authenticated users and some for unauthenticated users (public access)

My security.yaml file looks something like this:

security:

    enable_authenticator_manager: true

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
          custom_authenticators:
            - App\Security\JwtAuthenticator

    access_control:
      - { path: ^/auth/login, roles: PUBLIC_ACCESS }
      - { path: ^/auth, roles: ROLE_USER }

I have also setup a route to auth/login

However, when I access the url https://myapp.test/auth/login I get the following message:

{"message":"Invalid credentials."}

If I remove the custom authenticator directive from security.yaml the url loads as expected.

Below is the authenticate function from the Authenticator class:

public function authenticate(Request $request): PassportInterface
{
    return new SelfValidatingPassport(new UserBadge($request->get('email));
}

if I access /auth/login with a valid user matching the email address provided and with the ROLE_USER role, the page will load as expected. If I access it without providing an email address, the page will return the following (from the onAuthenticationFailure method):

{"message":"Invalid credentials."}

If I understand correctly, as stated in Symfony docs, the PUBLIC_ACCESS should skip authenticating the user and load the /auth/login route, while everything else under /auth/ should be protected. But I cannot get the PUBLIC_ACCESS directive to work.

Upvotes: 1

Views: 1735

Answers (1)

Joeker
Joeker

Reputation: 95

I resolved it by changing the location of custom_authenticators like that:

security:
    enable_authenticator_manager: true

    firewalls:
     main:
            json_login:                   # that is my login for rest api
                provider: user_provider
                check_path: api_login
     api:
            pattern: ^/api
            custom_authenticators:        # here is the location for my custom authenticator
                - App\Security\Authenticator
            stateless: true

     access_control:
        - { path: ^/login, roles: PUBLIC_ACCESS }

I hope it helps!

Upvotes: 2

Related Questions