|
@@ -9,22 +9,26 @@ 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
|
|
|
+ * @var TokenStorageInterface
|
|
|
*/
|
|
|
protected $tokenStorage;
|
|
|
|
|
|
/**
|
|
|
- * @var AuthenticationManagerInterface
|
|
|
+ * @var AuthenticationManagerInterface
|
|
|
*/
|
|
|
protected $authenticationManager;
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* @var AccessTokenService
|
|
|
*/
|
|
@@ -45,58 +49,81 @@ class OAuthProxyListener implements ListenerInterface
|
|
|
|
|
|
/**
|
|
|
* 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();
|
|
|
- $auth_info = array();
|
|
|
- if ($request->headers->has("php-auth-user") && $request->headers->has("php-auth-pw")) {
|
|
|
- $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);
|
|
|
+ // 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())) {
|
|
|
+ $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.
|
|
|
+ $error = false;
|
|
|
+ } else if ($request->headers->has("php-auth-user") && $request->headers->has("php-auth-pw")) {
|
|
|
+ // el header contiene php-auth-user && php-auth-pw
|
|
|
+ $error = !$this->PHPAuth($request);
|
|
|
} elseif ($request->headers->has("authorization")) {
|
|
|
- $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'];
|
|
|
- } else {
|
|
|
- return $this->deny($event);
|
|
|
- }
|
|
|
+ // el header contiene authorization
|
|
|
+ $error = !$this->PHPAuthorization($request);
|
|
|
} elseif ($request->getClientIp()) {
|
|
|
- $username = $clientIp = $request->getClientIp();
|
|
|
- if (\AuthBundle\Utils\IpUtils::checkIp($clientIp) === false) {
|
|
|
- return $this->deny($event);
|
|
|
- }
|
|
|
- // @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
|
|
|
- $tenancy = array(
|
|
|
- 'id' => 1,
|
|
|
- 'name' => 'Tenencia Base',
|
|
|
- );
|
|
|
- $auth_info['tenancies'] = $auth_info['tenancyCurrent'] = $tenancy;
|
|
|
+ $error = !$this->clientIp($request);
|
|
|
} else {
|
|
|
- return $this->deny($event);
|
|
|
+ $error = true;
|
|
|
}
|
|
|
-
|
|
|
+ if ($error) {
|
|
|
+ $this->deny($event);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @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)) {
|
|
@@ -107,32 +134,58 @@ class OAuthProxyListener implements ListenerInterface
|
|
|
|
|
|
$token = new OAuthToken($accessToken, $user->getRoles());
|
|
|
$token->setUser($user);
|
|
|
-
|
|
|
+
|
|
|
$authToken = $this->authenticationManager->authenticate($token);
|
|
|
$this->tokenStorage->setToken($authToken);
|
|
|
-
|
|
|
- return;
|
|
|
+
|
|
|
+ return true;
|
|
|
} catch (\Exception $failed) {
|
|
|
var_dump($failed->getMessage());
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
- $this->deny($event);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * @param GetResponseEvent $event
|
|
|
+ * @param Request $request
|
|
|
+ * @return bool Retorna TRUE si pudo crear y setear el CustomOAuthUser
|
|
|
*/
|
|
|
- private function deny(GetResponseEvent $event)
|
|
|
+ private function PHPAuthorization($request)
|
|
|
{
|
|
|
- $this->tokenStorage->setToken(null);
|
|
|
-
|
|
|
- $response = new Response();
|
|
|
- $response->setStatusCode(Response::HTTP_FORBIDDEN);
|
|
|
- $event->setResponse($response);
|
|
|
-
|
|
|
- echo 'The OAuth authentication failed.' . PHP_EOL;
|
|
|
-
|
|
|
- return;
|
|
|
+ $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
|
|
|
+ $tenancy = array(
|
|
|
+ 'id' => 1,
|
|
|
+ 'name' => 'Tenencia Base',
|
|
|
+ );
|
|
|
+ $auth_info['tenancies'] = $auth_info['tenancyCurrent'] = $tenancy;
|
|
|
+ return $this->createCustomOAuthUser($username, $accessToken, $auth_info);
|
|
|
+ }
|
|
|
+}
|