I have a project that use Symfony API-Platform. I want to use LexikJWTAuthenticationBundle on my project but my users are stored in an Active Directory so I set an LDAP UserProvider. I tried to combine the setting of the two following documentation without success :
Here is what I have done
In security.yml :
security:
providers:
my_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: OU=organization_unit,DC=domain,DC=local
search_dn: "OU=organization_unit,DC=domain,DC=local"
search_password: '%env(resolve:LDAP_PASSWORD)%'
default_roles: ROLE_USER
uid_key: uid
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
provider: my_ldap
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
guard:
provider: my_ldap
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
In services.yml :
Symfony\Component\Ldap\Ldap:
arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: '%env(resolve:LDAP_HOST)%'
port: 636
# encryption: tls
options:
protocol_version: 3
referrals: false
But when I try to send the request to my_domain/api/login_check with following content :
{
"username": "my_user",
"password": "my_password"
}
I received this error as response:
{"code":401,"message":"Invalid credentials."}
I have resolved my issue by using a custom action that checks if the user exist using LDAP and get its roles. Then, if the freshly retrieved user is authorized to use the application, I create a new token and return it in the response. And finally the token is used to authentify the user for each call he do to the API.
Here is my security.yml
providers:
# provider to retrieve user from LDAP
my_ldap:
id: App\Security\LdapService
# provider to retrieve user from user
jwt:
lexik_jwt:
class: App\Security\User
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
api:
pattern: ^/api/
stateless: true
guard:
provider: jwt
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
The login action in controller :
/**
* @Route("/api/login", name="api_login", methods={"POST"})
*/
public function loginCheck(Request $request, LdapService $ldapService, AuthenticationSuccessHandler $authenticationSuccessHandler, AuthenticationFailureHandler $authenticationFailureHandler){
$content = json_decode($request->getContent());
$response= new JsonResponse();
try{
$user=$ldapService->authenticate($content->username, $content->password);
return $authenticationSuccessHandler->handleAuthenticationSuccess($user);
}catch(AuthenticationException $e){
return $authenticationFailureHandler->onAuthenticationFailure($request, $e);
}
return $response;
}