zend-blog-3-backend
92 строки · 2.7 Кб
1<?php
2
3namespace App\Security\Authentication\Provider;
4
5use App\Entity\User;
6use App\Security\Authentication\Token\WsseUserToken;
7use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
8use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
9use Symfony\Component\Security\Core\Exception\AuthenticationException;
10use Symfony\Component\Security\Core\Exception\BadCredentialsException;
11use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
12use Symfony\Component\Security\Core\User\UserProviderInterface;
13
14class WsseAuthenticationProvider implements AuthenticationProviderInterface
15{
16/**
17* @var UserProviderInterface
18*/
19private $userProvider;
20
21private int $lifetime;
22
23/**
24* @param UserProviderInterface $userProvider
25* @param int $lifetime
26*/
27public function __construct(UserProviderInterface $userProvider, int $lifetime = 300)
28{
29$this->userProvider = $userProvider;
30$this->lifetime = $lifetime;
31}
32
33/**
34* @param TokenInterface $token
35*
36* @return WsseUserToken
37*/
38public function authenticate(TokenInterface $token)
39{
40$user = $this->userProvider->loadUserByIdentifier($token->getUserIdentifier());
41
42if ($user instanceof User
43&& $this->validateDigest($token, $user->getWsseKey())
44) {
45$authenticatedToken = new WsseUserToken($user->getRoles());
46$authenticatedToken->setUser($user);
47
48return $authenticatedToken;
49}
50
51throw new AuthenticationException('The WSSE authentication failed.');
52}
53
54/**
55* @param TokenInterface $token
56*
57* @return bool
58*/
59public function supports(TokenInterface $token)
60{
61return $token instanceof WsseUserToken
62&& $token->hasAttribute('nonce')
63&& $token->hasAttribute('digest')
64&& $token->hasAttribute('created');
65}
66
67/**
68* @param TokenInterface $token
69* @param string $wsseKey
70*
71* @return bool
72*/
73private function validateDigest(TokenInterface $token, string $wsseKey): bool
74{
75$nonce = $token->getAttribute('nonce');
76$digest = $token->getAttribute('digest');
77$createdAt = strtotime($token->getAttribute('created'));
78if (!$createdAt) {
79throw new BadCredentialsException('Incorrectly formatted "created" in token.');
80}
81
82if (abs($createdAt - time()) > $this->lifetime) {
83throw new CredentialsExpiredException('Token has expired.');
84}
85
86$expected = base64_encode(
87sha1(base64_decode($nonce) . $token->getAttribute('created') . $wsseKey, true)
88);
89
90return hash_equals($expected, $digest);
91}
92}
93