src/Misc/AppAuthenticator.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\Misc;
  3. use Symfony\Component\HttpFoundation\JsonResponse;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  8. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  9. use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
  10. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  11. use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
  12. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  13. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  14. use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
  15. use App\Exception\AccessDeniedException;
  16. use App\Entity\User;
  17. class AppAuthenticator extends AbstractAuthenticator
  18. {
  19.     /**
  20.      * Called on every request to decide if this authenticator should be
  21.      * used for the request. Returning `false` will cause this authenticator
  22.      * to be skipped.
  23.      */
  24.     public function supports(Request $request): ?bool
  25.     {
  26.         return $request->headers->has('X-W-Auth');
  27.     }
  28.     public function authenticate(Request $request): PassportInterface
  29.     {
  30.         $authRegex '/UsernameToken Email="(?P<email>[^"]+)", PasswordDigest="(?P<digest>[^"]+)", Nonce="(?P<nonce>[a-zA-Z0-9+\/]+={0,2})", Created="(?P<created>[^"]+)"/';
  31.         if (
  32.             !== preg_match($authRegex$request->headers->get('X-W-Auth'), $matches)
  33.             || $matches['email'] == 'undefined'
  34.         ) {
  35.             throw new AccessDeniedException(AccessDeniedException::INVALID_TOKEN'token check');
  36.         }
  37.         return new Passport(new UserBadge($matches['email']), new CustomCredentials(
  38.             function ($credentialsUser $user) use ($request) {
  39.                 if (!$user->getAuthPermitted()) {
  40.                     throw new AccessDeniedException(AccessDeniedException::NOT_PERMITTED'authenticate');
  41.                 }
  42.                 $rawString $credentials['nonce'] . $credentials['created'] . hash('sha256'$user->getPassword());
  43.                 $expected hash('sha256'$rawString);
  44.                 return hash_equals($expected$credentials['digest']);
  45.             },
  46.             [
  47.                 'digest'  => $matches['digest'],
  48.                 'nonce'   => $matches['nonce'],
  49.                 'created' => $matches['created'],
  50.                 'host'    => $request->getHost(),
  51.             ]
  52.         ));
  53.     }
  54.     public function onAuthenticationSuccess(Request $requestTokenInterface $tokenstring $firewallName): ?Response
  55.     {
  56.         // on success, let the request continue
  57.         return null;
  58.     }
  59.     public function onAuthenticationFailure(Request $requestAuthenticationException $exception): ?Response
  60.     {
  61.         throw new AccessDeniedException(AccessDeniedException::WRONG_TOKEN'token check');
  62.     }
  63. }