我正在使用Symfony 4.3构建REST Api,并且使用自定义用户提供程序和自定义保护程序进行身份验证(用户/密码)时遇到问题。
上下文
用户必须使用用户/密码在特定端点/ api / auth / login上对自己进行身份验证才能获取JWT令牌。所有用户都存储在用户表中,其中包含以下信息:
如果身份验证方法是在“ LOCAL”上定义的,则我们在用户表中使用登录名/密码定义来对其进行身份验证。如果身份验证方法是在“ LDAP”上定义的,则我只想使用登录名(数据库中没有存储密码),并根据LDAP对用户进行身份验证。
我已经创建了一个自定义用户提供程序来管理我的User类,并且我已经创建了一个自定义Guard身份验证器,以便管理这两种身份验证方法:
class MyUserAuthenticator extends AbstractGuardAuthenticator
{
private $em;
private $logger;
private $userRepository;
public function __construct(EntityManagerInterface $em, TUserRepository $userRepository)
{
$this->em = $em;
$this->userRepository = $userRepository;
}
public function getCredentials(Request $request)
{
$this->logger->info('[UserAuthenticator] getCredentials()');
$data = json_decode($request->getContent(), true);
if(isset($data['username']) && isset($data['password'])) {
$credentials = [
'username' => $data['username'],
'password' => $data['password'],
];
return $credentials;
} else {
throw new BadCredentialsException('username or/and password missing in login request.');
}
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$this->logger->info('[UserAuthenticator] getUser()');
return $this->userRepository->find($credentials['username']);
}
public function checkCredentials($credentials, UserInterface $user)
{
if($user){
$mode = $user->getAuthMethod();
switch($mode) {
case 'LDAP':
// CHECK ON LDAP
break;
case 'LOCAL':
// CHECK password with the User Provider
// if($user->getPassword() == credentials['password']) { return true; } else { return false; }
break;
default:
return false;
break;
}
}
// return true to cause authentication success
return false;
}
}
问题
我的自定义身份验证器保护程序的checkCredentials()可以正常工作,它返回TRUE,并且我已通过保护程序进行了身份验证(日志文件中的Guard身份验证成功)。 但是之后,Symfony似乎还有另一个身份验证过程处理,它会检查密码,如果我使用LDAP authen方法(数据库中没有密码),最终身份验证将失败:
[2019-09-27 17:02:55] security.INFO:身份验证请求失败。 {“ exception”:“ [对象](Symfony \ Component \ Security \ Core \ Exception \ BadCredentialsException(代码:0):错误的凭据。位于/var/www/my.api/vendor/symfony/security-core/Authentication/ Provider / UserAuthenticationProvider.php:85,Symfony \ Component \ Security \ Core \ Exception \ BadCredentialsException(代码:0):所提供的密码无效。位于/var/www/my.api/vendor/symfony/security-core/Authentication /Provider/DaoAuthenticationProvider.php:59)“} []
我不理解为什么要检查密码,我公正地决定创建我的自定义身份验证器保护程序,以实施自定义密码管理...
日志文件:
[2019-09-27 17:02:55] request.INFO: Matched route "api_auth_login". {"route":"api_auth_login","route_parameters":{"_route":"api_auth_login"},"request_uri":"https://my.api/api/auth/login","method":"POST"} []
[2019-09-27 17:02:55] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"api_login","authenticators":1} []
[2019-09-27 17:02:55] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"api_login","authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] security.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"api_login","authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] app.INFO: [UserAuthenticator] getCredentials() [] []
[2019-09-27 17:02:55] security.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"api_login","authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] app.INFO: [UserAuthenticator] getUser() [] []
[2019-09-27 17:02:55] doctrine.DEBUG: SELECT [.......] WHERE t0.USERID = ? ["THEUSER"] []
[2019-09-27 17:02:55] app.INFO: [UserAuthenticator] checkCredentials() [] []
[2019-09-27 17:02:55] security.INFO: Guard authentication successful! {"token":"[object] (Symfony\\Component\\Security\\Guard\\Token\\PostAuthenticationGuardToken: PostAuthenticationGuardToken(user=\"THEUSER\", authenticated=true, roles=\"SUPERVISER\"))","authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] security.DEBUG: Guard authenticator set no success response: request continues. {"authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] security.DEBUG: Remember me skipped: it is not configured for the firewall. {"authenticator":"App\\Security\\UserAuthenticator"} []
[2019-09-27 17:02:55] app.INFO: loadUserByUsername() [] []
[2019-09-27 17:02:55] security.INFO: Authentication request failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Bad credentials. at /var/www/my.api/vendor/symfony/security-core/Authentication/Provider/UserAuthenticationProvider.php:85, Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): The presented password is invalid. at /var/www/my.api/vendor/symfony/security-core/Authentication/Provider/DaoAuthenticationProvider.php:59)"} []