I am trying to create a hybrid api-token/form login security using Symfony's (2.8.24) guard mechanism.
My security.yml looks like this:
security:
acl:
connection: default
providers:
jwt:
id: app.jwt_user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
guard:
entry_point: app.jwt_authenticator
authenticators:
- app.jwt_authenticator
- app.authenticator.form_login
provider: jwt
access_control:
- { path: ^/general/info, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: IS_AUTHENTICATED_FULLY }
So I have a main firewall with two configured authenticators. The entry point is the app.jwt_authenticator, with a fallback to the app.authenticator.form_login.
I want it so that when no token is present, that the app.jwt_authenticator is skipped.
The getCredentials() method of the app.jwt_authenticator looks like this basically:
public function getCredentials(Request $request): ?string
{
$tokenString = $request->headers->get('Authorization');
if (!$tokenString) {
$this->logger->warn('No authorization header');
return null;
}
return $tokenString;
}
So if there is no Authorization header it returns null.
And according to Symfony's documentation:
Get the authentication credentials from the request and return them as any type (e.g. an associate array). If you return null, authentication will be skipped.
So I would expect this authenticator to be skipped when there is no Authorization header, but unfortunately that is not the case.
Even though getCredentials() returns null (and I have verified that it does), the start() method gets called instead of skipping this authenticator and moving on to the next.
Is my configuration not correct? Am I misunderstanding the mechanism?
What do I need to do to implement this hybrid?