/**
* Handles digest authentication.
*
* @param Event $event An Event instance
*/
public function handle(Event $event)
{
$request = $event->getParameter('request');
if (!($header = $request->server->get('PHP_AUTH_DIGEST'))) {
return;
}
if (null !== ($token = $this->securityContext->getToken())) {
if ($token->isImmutable()) {
return;
}
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && (string) $token === $username) {
return;
}
}
if (null !== $this->logger) {
$this->logger->debug(sprintf('Digest Authorization header received from user agent: %s', $header));
}
$digestAuth = new DigestData($header);
try {
$digestAuth->validateAndDecode($this->authenticationEntryPoint->getKey(), $this->authenticationEntryPoint->getRealmName());
} catch (BadCredentialsException $e) {
$this->fail($request, $e);
return;
}
try {
$user = $this->provider->loadUserByUsername($digestAuth->getUsername());
if (null === $user) {
throw new AuthenticationServiceException('AuthenticationDao returned null, which is an interface contract violation');
}
$serverDigestMd5 = $digestAuth->calculateServerDigest($user->getPassword(), $request->getMethod());
} catch (UsernameNotFoundException $notFound) {
$this->fail($request, new BadCredentialsException(sprintf('Username %s not found.', $digestAuth->getUsername())));
return;
}
if ($serverDigestMd5 !== $digestAuth->getResponse()) {
if (null !== $this->logger) {
$this->logger->debug(sprintf("Expected response: '%s' but received: '%s'; is AuthenticationDao returning clear text passwords?", $serverDigestMd5, $digestAuth->getResponse()));
}
$this->fail($request, new BadCredentialsException('Incorrect response'));
return;
}
if ($digestAuth->isNonceExpired()) {
$this->fail($request, new NonceExpiredException('Nonce has expired/timed out.'));
return;
}
if (null !== $this->logger) {
$this->logger->debug(sprintf('Authentication success for user "%s" with response "%s"', $digestAuth->getUsername(), $digestAuth->getResponse()));
}
$this->securityContext->setToken(new UsernamePasswordToken($user, $user->getPassword()));
}