123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- <?php
- namespace AuthBundle\Security\Firewall;
- use AuthBundle\Services\AccessTokenService;
- use Base\OAuthClientBundle\Security\Core\User\CustomOAuthUser;
- use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
- use Monolog\Logger;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\Event\GetResponseEvent;
- use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
- use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
- use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
- use Symfony\Component\Security\Core\Exception\AuthenticationException;
- use Symfony\Component\Security\Core\Exception\BadCredentialsException;
- use Symfony\Component\Security\Http\Firewall\ListenerInterface;
- use Symfony\Component\HttpFoundation\Request;
- class OAuthProxyListener implements ListenerInterface
- {
- /**
- * @var TokenStorageInterface
- */
- protected $tokenStorage;
- /**
- * @var AuthenticationManagerInterface
- */
- protected $authenticationManager;
- /**
- * @var AccessTokenService
- */
- protected $accessTokenService;
- /**
- * @var Logger
- */
- private $logger;
- /**
- * @param TokenStorageInterface $tokenStorage
- * @param AuthenticationManagerInterface $authenticationManager
- * @param AccessTokenService $accessTokenService
- */
- public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessTokenService $accessTokenService)
- {
- $this->tokenStorage = $tokenStorage;
- $this->authenticationManager = $authenticationManager;
- $this->accessTokenService = $accessTokenService;
- }
- /**
- * @param Logger $logger
- */
- public function setLogger(Logger $logger)
- {
- $this->logger = $logger;
- }
- /**
- * Se crea el User y Token mediante alguno de los métodos
- *
- * 1. Http Basic
- * 2. Authorization
- * 3. Client Ip
- * 4. Firewalls
- *
- * @param GetResponseEvent $event
- * @return type
- *
- */
- public function handle(GetResponseEvent $event)
- {
- $request = $event->getRequest();
- $messageLog = "";
- // verifico si la ip esta bloqueada. Se utiliza la variable API_CIDR_DENY para almacenar las ip o rangos de ip
- if (\AuthBundle\Utils\IpUtils::checkIpDeny($request->getClientIp())) {
- $messageLog = "Deny IP: " . $request->getClientIp();
- $error = true;
- } else if (($this->tokenStorage != null &&
- $this->tokenStorage->getToken() != null &&
- $this->tokenStorage->getToken() instanceof OAuthToken)) {
- // como los firewalls comparten info a traves del context no tengo que hacer nada, ya esta logueado.
- $messageLog = "Firewalls (IP: " . $request->getClientIp() . ")";
- $error = false;
- } else if ($request->headers->has("php-auth-user") && $request->headers->has("php-auth-pw")) {
- $messageLog = "PHP-AUTH (IP: " . $request->getClientIp() . ")";
- // el header contiene php-auth-user && php-auth-pw
- $error = !$this->PHPAuth($request);
- } elseif ($request->headers->has("authorization")) {
- $messageLog = "AUTHORIZATION A (IP: " . $request->getClientIp() . ")";
- // el header contiene authorization
- $error = !$this->PHPAuthorization($request);
- } elseif ($request->getClientIp()) {
- $messageLog = "AUTHORIZATION B (IP: " . $request->getClientIp() . ")";
- $error = !$this->clientIp($request);
- } else {
- $messageLog = "NO REFERENCE. DENY ALL.";
- $error = true;
- }
- if ($error) {
- $this->logger->info("ERROR - " . $messageLog);
- $this->deny($event);
- } else {
- $this->logger->info("OK - " . $messageLog);
- }
- }
- /**
- * @param GetResponseEvent $event
- */
- private function deny(GetResponseEvent $event)
- {
- $this->tokenStorage->setToken(null);
- $response = new Response();
- $response->setStatusCode(Response::HTTP_FORBIDDEN);
- $event->setResponse($response);
- echo 'The OAuth authentication failed.' . PHP_EOL;
- return;
- }
- /**
- * @param Request $request
- * @return bool Retorna TRUE si pudo crear y setear el CustomOAuthUser
- */
- private function PHPAuth(Request $request)
- {
- $username = $request->headers->get("php-auth-user");
- $password = $request->headers->get("php-auth-pw");
- $token = $this->accessTokenService->getToken($username, $password);
- unset($token['user_info']);
- $accessToken = $token;
- $auth_info = $this->accessTokenService->getUserInfo($username, $password);
- return $this->createCustomOAuthUser($username, $accessToken, $auth_info);
- }
- /**
- * Crea el custom user.
- * @param string $username
- * @param array $accessToken
- * @param array $auth_info
- * @return bool Retorna TRUE si pudo crear el CustomOAuthUser
- */
- private function createCustomOAuthUser(string $username, array $accessToken, array $auth_info)
- {
- try {
- $user = new CustomOAuthUser($username);
- if (count($auth_info)) {
- $user->setRoles($auth_info['roles']);
- $user->setTenancies($auth_info['tenancies']);
- $user->setTenancyCurrent($auth_info['tenancyCurrent']);
- $user->setHasIntercom($auth_info['hasIntercom']);
- }
- $token = new OAuthToken($accessToken, $user->getRoles());
- $token->setUser($user);
- $authToken = $this->authenticationManager->authenticate($token);
- $this->tokenStorage->setToken($authToken);
- return true;
- } catch (\Exception $failed) {
- //var_dump($failed->getMessage());
- return false;
- }
- }
- /**
- * @param Request $request
- * @return bool Retorna TRUE si pudo crear y setear el CustomOAuthUser
- */
- private function PHPAuthorization($request)
- {
- $authorization = $request->headers->get("authorization");
- $pieces = explode(' ', $authorization);
- $accessToken = array(
- 'access_token' => $pieces[1],
- );
- $auth_info = $this->accessTokenService->requestUserInfo($authorization);
- if (isset($auth_info['username'])) {
- $username = $auth_info['username'];
- return $this->createCustomOAuthUser($username, $accessToken, $auth_info);
- } else {
- return false;
- }
- }
- /**
- * @param Request $request
- * @return bool Retorna TRUE si pudo crear y setear el CustomOAuthUser
- */
- private function clientIp($request)
- {
- $username = $clientIp = $request->getClientIp();
- if (\AuthBundle\Utils\IpUtils::checkIp($clientIp) === false) {
- return false;
- }
- // @TODO: Generar access token para el caso de IP valida
- $accessToken = array(
- 'access_token' => '',
- );
- $auth_info['roles'] = array('ROLE_USER');
- // @TODO: Traer la tenencia Base de la app Base
- $filter = $request->query->get('filters');
- if(isset($filter['tenancyId']) && $filter['tenancyId'] != 1) {
- $tenancy = array(
- array('id' => 1,'name' => 'Tenencia Base',),
- array('id' => (int) $filter['tenancyId'], 'name' => 'Tenancy Fix'));
- } else {
- $tenancy = array(array(
- 'id' => 1,
- 'name' => 'Tenencia Base',
- ));
- }
- $auth_info['tenancies'] = $tenancy;
- $auth_info['tenancyCurrent'] = end($tenancy);
- return $this->createCustomOAuthUser($username, $accessToken, $auth_info);
- }
- }
|