Selaa lähdekoodia

Tarea FD3-176. ProxyAuthenticator

Your Name 7 vuotta sitten
vanhempi
commit
62c2612abe
2 muutettua tiedostoa jossa 133 lisäystä ja 1 poistoa
  1. 8 1
      Resources/config/services.yml
  2. 125 0
      Security/OAuthProxyAuthenticator.php

+ 8 - 1
Resources/config/services.yml

@@ -4,4 +4,11 @@ services:
         class: Base\OAuthClientBundle\EventListener\RequestListener
         tags:
             - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
-        arguments: [ '@security.token_storage', '%client_id%', '%client_secret%', '%access_token_url%' ]
+        arguments: [ '@security.token_storage', '%client_id%', '%client_secret%', '%access_token_url%' ]
+    
+    base_oauthclient_security_oauthproxyauthenticator:
+        class: Base\OAuthClientBundle\Security\OAuthProxyAuthenticator 
+        arguments: [ '%client_id%', '%client_secret%', '%access_token_url%', '%infos_url%' ]
+
+    base_oauthclient_security_oauthproxyprovider:
+        class: Base\OAuthClientBundle\Security\OAuthProxyUserProvider

+ 125 - 0
Security/OAuthProxyAuthenticator.php

@@ -0,0 +1,125 @@
+<?php
+namespace Base\OAuthClientBundle\Security;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
+
+use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
+
+use Buzz\Listener\BasicAuthListener;
+use Buzz\Message;
+
+use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
+
+use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+
+class OAuthProxyAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface
+{
+    public function __construct($client_id, $client_secret, $access_token_url, $user_info_url)
+    {
+	    $this->client_id  = $client_id;
+	    $this->client_secret = $client_secret;
+	    $this->access_token_url = $access_token_url;
+	    $this->user_info_url = $user_info_url;
+    }
+
+    public function createToken(Request $request, $providerKey)
+    {
+	if($request->headers->has("php-auth-user") and $request->headers->has("php-auth-pw"))
+		return new PreAuthenticatedToken($request->headers->get("php-auth-user"), $request->headers->get("php-auth-pw"), $providerKey);
+	return new AnonymousToken("anon.", "anon.");
+
+    }
+
+    public function supportsToken(TokenInterface $token, $providerKey)
+    {
+        return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
+    }
+
+    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
+    {
+ 	$password = $token->getCredentials();
+	$username = $token->getUsername();
+
+	
+	$token = @json_decode(file_get_contents("/tmp/.".base64_encode($username. ":" . $password)), true);
+	
+	if(!isset($token["access_token"])){
+		$browser = new \Buzz\Browser();
+
+		$listener = new BasicAuthListener($this->client_id, $this->client_secret);
+		$browser->addListener($listener);
+		$body = ['grant_type' => 'password',
+			'username' => $username,
+			'password' => $password,
+			];
+
+		$response = $browser->post($this->access_token_url, ['Content-Type' => 'application/x-www-form-urlencoded'], http_build_query($body));
+		$token = json_decode($response->getContent(), true);
+		if($token['expires_in'])
+			$token["expires_at"] = time() + $token['expires_in'];
+		else
+			$token["expires_at"] = time() + 3600;
+
+		file_put_contents("/tmp/.".base64_encode($username. ":" . $password), json_encode($token));
+	}
+
+	if(isset($token["expires_at"]) and $token["expires_at"] >= time()){
+		$browser = new \Buzz\Browser();
+
+		$listener = new BasicAuthListener($this->client_id, $this->client_secret);
+		$browser->addListener($listener);
+
+		$body = ['grant_type' => 'refresh_token',
+			 'refresh_token' => $token['refresh_token']
+			];
+
+
+		$response = $browser->post($this->access_token_url, ['Content-Type' => 'application/x-www-form-urlencoded'], http_build_query($body));
+		$token = json_decode($response->getContent(), true);
+		if($token['expires_in'])
+			$token["expires_at"] = time() + $token['expires_in'];
+		else
+			$token["expires_at"] = time() + 3600;
+
+		file_put_contents("/tmp/.".base64_encode($username. ":" . $password), json_encode($token));
+	}
+
+	if(!isset($token["user_info"])){
+
+		$oauth_headers = [
+			"Authorization" => ucfirst($token["token_type"])." ".$token["access_token"],
+		];
+
+		$browser = new \Buzz\Browser();
+
+		$response = $browser->get($this->user_info_url, $oauth_headers);
+		$auth_info = json_decode($response->getContent(), true);
+		$token["user_info"] = $auth_info;
+
+		file_put_contents("/tmp/.".base64_encode($username. ":" . $password), json_encode($token));
+	}else{
+		$auth_info = $token["user_info"];
+	}
+
+	$user = $userProvider->loadUserByUsername($auth_info["username"]);
+	$user->setRoles($auth_info["roles"]);
+	$user->setTenancyCurrent($auth_info["tenancyCurrent"]);
+        return new PreAuthenticatedToken($user, array(), $providerKey, $user->getRoles());
+    }
+
+    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+    {
+	 return new Response(
+	// this contains information about *why* authentication failed
+	// use it, or return your own message
+		strtr($exception->getMessageKey(), $exception->getMessageData()), 401);
+    }
+}