Kaynağa Gözat

OAuth proxy

root 7 yıl önce
ebeveyn
işleme
84a1bdde77

+ 10 - 1
Resources/config/services.yml

@@ -4,4 +4,13 @@ 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
+
+

+ 89 - 0
Security/OAuthProxyAuthenticator.php

@@ -0,0 +1,89 @@
+<?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 Symfony\Component\HttpFoundation\Session\Session;
+
+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)
+    {
+        return new PreAuthenticatedToken($request->headers->get("php-auth-user"), $request->headers->get("php-auth-pw"), $providerKey);
+    }
+
+    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));
+	}
+
+	$oauth_headers = [
+		"Authorization" => ucfirst($token["token_type"])." ".$token["access_token"],
+	];
+
+	$browser = new \Buzz\Browser();
+
+	$listener = new BasicAuthListener($this->client_id, $this->client_secret);
+	$response = $browser->get($this->user_info_url, $oauth_headers);
+	$auth_info = json_decode($response->getContent(), true);
+
+        return new PreAuthenticatedToken( $auth_info["username"], "", $providerKey, $auth_info["roles"]);
+    }
+
+    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);
+    }
+}

+ 44 - 0
Security/OAuthProxyUserProvider.php

@@ -0,0 +1,44 @@
+<?php
+namespace Base\OAuthClientBundle\Security;
+
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Core\User\User;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
+
+class OAuthProxyUserProvider implements UserProviderInterface
+{
+    public function getUsernameForApiKey($apiKey)
+    {
+        // Look up the username based on the token in the database, via
+        // an API call, or do something entirely different
+        $username = "nose"; 
+
+        return $username;
+    }
+
+    public function loadUserByUsername($username)
+    {
+        return new User(
+            $username,
+            null,
+            // the roles for the user - you may choose to determine
+            // these dynamically somehow based on the user
+            array('ROLE_API')
+        );
+    }
+
+    public function refreshUser(UserInterface $user)
+    {
+        // this is used for storing authentication in the session
+        // but in this example, the token is sent in each request,
+        // so authentication can be stateless. Throwing this exception
+        // is proper to make things stateless
+        throw new UnsupportedUserException();
+    }
+
+    public function supportsClass($class)
+    {
+        return User::class === $class;
+    }
+}