]>
Commit | Line | Data |
---|---|---|
c3235553 NL |
1 | <?php |
2 | namespace Wallabag\CoreBundle\Security\Authentication\Provider; | |
3 | ||
4 | use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; | |
5 | use Symfony\Component\Security\Core\User\UserProviderInterface; | |
6 | use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
7 | use Symfony\Component\Security\Core\Exception\NonceExpiredException; | |
8 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |
9 | use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken; | |
10 | ||
11 | class WsseProvider implements AuthenticationProviderInterface | |
12 | { | |
13 | private $userProvider; | |
14 | private $cacheDir; | |
15 | ||
16 | public function __construct(UserProviderInterface $userProvider, $cacheDir) | |
17 | { | |
18 | $this->userProvider = $userProvider; | |
19 | $this->cacheDir = $cacheDir; | |
92504e0d NL |
20 | |
21 | // If cache directory does not exist we create it | |
22 | if (!is_dir($this->cacheDir)) { | |
23 | mkdir($this->cacheDir, 0777, true); | |
24 | } | |
c3235553 NL |
25 | } |
26 | ||
27 | public function authenticate(TokenInterface $token) | |
28 | { | |
29 | $user = $this->userProvider->loadUserByUsername($token->getUsername()); | |
30 | ||
2a94b1d1 NL |
31 | if (!$user) { |
32 | throw new AuthenticationException("Bad credentials. Did you forgot your username?"); | |
33 | } | |
34 | ||
c3235553 NL |
35 | if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) { |
36 | $authenticatedToken = new WsseUserToken($user->getRoles()); | |
37 | $authenticatedToken->setUser($user); | |
38 | ||
39 | return $authenticatedToken; | |
40 | } | |
41 | ||
42 | throw new AuthenticationException('The WSSE authentication failed.'); | |
43 | } | |
44 | ||
45 | protected function validateDigest($digest, $nonce, $created, $secret) | |
46 | { | |
2a94b1d1 NL |
47 | // Check created time is not in the future |
48 | if (strtotime($created) > time()) { | |
49 | throw new AuthenticationException("Back to the future..."); | |
50 | } | |
51 | ||
52 | // Expire timestamp after 5 minutes | |
c3235553 | 53 | if (time() - strtotime($created) > 300) { |
2a94b1d1 | 54 | throw new AuthenticationException("Too late for this timestamp... Watch your watch."); |
c3235553 NL |
55 | } |
56 | ||
2a94b1d1 | 57 | // Validate nonce is unique within 5 minutes |
c3235553 NL |
58 | if (file_exists($this->cacheDir.'/'.$nonce) && file_get_contents($this->cacheDir.'/'.$nonce) + 300 > time()) { |
59 | throw new NonceExpiredException('Previously used nonce detected'); | |
60 | } | |
0ac38198 | 61 | |
c3235553 NL |
62 | file_put_contents($this->cacheDir.'/'.$nonce, time()); |
63 | ||
2a94b1d1 | 64 | // Validate Secret |
c3235553 NL |
65 | $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true)); |
66 | ||
2a94b1d1 NL |
67 | if ($digest !== $expected) { |
68 | throw new AuthenticationException("Bad credentials ! Digest is not as expected."); | |
69 | } | |
70 | ||
c3235553 NL |
71 | return $digest === $expected; |
72 | } | |
73 | ||
74 | public function supports(TokenInterface $token) | |
75 | { | |
76 | return $token instanceof WsseUserToken; | |
77 | } | |
7df80cb3 | 78 | } |