Implements: blueprint openid-oauth2-implicit-client-flow
Change-Id: Iee3c9412a3f75a4aba5421e8c5f881a60b396df0
This commit is contained in:
parent
946b7dd8ae
commit
ad1844984e
10
.gitignore
vendored
10
.gitignore
vendored
@ -5,8 +5,8 @@ composer.lock
|
||||
.DS_Storeapp/storage
|
||||
/app/storage/*
|
||||
.idea/*
|
||||
app/config/dev/database.php
|
||||
app/config/testing/database.php
|
||||
app/config/local/database.php
|
||||
app/config/production/database.php
|
||||
app/config/staging/database.php
|
||||
app/config/dev/*
|
||||
app/config/testing/*
|
||||
app/config/local/*
|
||||
app/config/production/*
|
||||
app/config/staging/*
|
||||
|
@ -310,17 +310,40 @@ class TestSeeder extends Seeder {
|
||||
)
|
||||
);
|
||||
|
||||
$client = Client::where('app_name','=','oauth2_test_app')->first();
|
||||
Client::create(
|
||||
array(
|
||||
'app_name' => 'oauth2_test_app_public',
|
||||
'app_description' => 'oauth2_test_app_public',
|
||||
'app_logo' => null,
|
||||
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client',
|
||||
'client_secret' => 'ITK/6Y5N7kOtGKhg',
|
||||
'client_type' => IClient::ClientType_Public,
|
||||
'user_id' => $user->id,
|
||||
'rotate_refresh_token' => true,
|
||||
'use_refresh_token' => true
|
||||
)
|
||||
);
|
||||
|
||||
$client_confidential = Client::where('app_name','=','oauth2_test_app')->first();
|
||||
$client_public = Client::where('app_name','=','oauth2_test_app_public')->first();
|
||||
//attach scopes
|
||||
$scopes = ApiScope::get();
|
||||
foreach($scopes as $scope){
|
||||
$client->scopes()->attach($scope->id);
|
||||
$client_confidential->scopes()->attach($scope->id);
|
||||
$client_public->scopes()->attach($scope->id);
|
||||
}
|
||||
//add uris
|
||||
ClientAuthorizedUri::create(
|
||||
array(
|
||||
'uri'=>'https://www.test.com/oauth2',
|
||||
'client_id'=>$client->id
|
||||
'client_id'=>$client_confidential->id
|
||||
)
|
||||
);
|
||||
|
||||
ClientAuthorizedUri::create(
|
||||
array(
|
||||
'uri'=>'https://www.test.com/oauth2',
|
||||
'client_id'=>$client_public->id
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -11,7 +11,7 @@ interface IOAuth2Protocol {
|
||||
* @param OAuth2Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function authorize(OAuth2Request $request);
|
||||
public function authorize(OAuth2Request $request = null);
|
||||
|
||||
/**
|
||||
* Token Endpoint
|
||||
@ -19,7 +19,7 @@ interface IOAuth2Protocol {
|
||||
* @param OAuth2Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function token(OAuth2Request $request);
|
||||
public function token(OAuth2Request $request = null);
|
||||
|
||||
/**
|
||||
* Get all available grant types set on the protocol
|
||||
|
@ -21,6 +21,7 @@ use oauth2\exceptions\UnsupportedResponseTypeException;
|
||||
|
||||
use oauth2\exceptions\UriNotAllowedException;
|
||||
use oauth2\grant_types\AuthorizationCodeGrantType;
|
||||
use oauth2\grant_types\ImplicitGrantType;
|
||||
use oauth2\grant_types\ValidateBearerTokenGrantType;
|
||||
use oauth2\grant_types\RefreshBearerTokenGrantType;
|
||||
|
||||
@ -34,6 +35,7 @@ use oauth2\services\ITokenService;
|
||||
use oauth2\services\IApiScopeService;
|
||||
|
||||
use oauth2\strategies\IOAuth2AuthenticationStrategy;
|
||||
use oauth2\strategies\OAuth2IndirectErrorResponseFactoryMethod;
|
||||
use utils\services\IAuthService;
|
||||
use utils\services\ICheckPointService;
|
||||
|
||||
@ -50,15 +52,15 @@ use utils\services\ILogService;
|
||||
class OAuth2Protocol implements IOAuth2Protocol
|
||||
{
|
||||
|
||||
const OAuth2Protocol_GrantType_AuthCode = 'authorization_code';
|
||||
const OAuth2Protocol_GrantType_Implicit = 'implicit';
|
||||
const OAuth2Protocol_GrantType_AuthCode = 'authorization_code';
|
||||
const OAuth2Protocol_GrantType_Implicit = 'implicit';
|
||||
const OAuth2Protocol_GrantType_ResourceOwner_Password = 'password';
|
||||
const OAuth2Protocol_GrantType_ClientCredentials = 'client_credentials';
|
||||
const OAuth2Protocol_GrantType_RefreshToken = 'refresh_token';
|
||||
const OAuth2Protocol_ResponseType_Code = 'code';
|
||||
const OAuth2Protocol_ResponseType_Token = 'token';
|
||||
const OAuth2Protocol_ResponseType = "response_type";
|
||||
const OAuth2Protocol_ClientId = "client_id";
|
||||
const OAuth2Protocol_GrantType_ClientCredentials = 'client_credentials';
|
||||
const OAuth2Protocol_GrantType_RefreshToken = 'refresh_token';
|
||||
const OAuth2Protocol_ResponseType_Code = 'code';
|
||||
const OAuth2Protocol_ResponseType_Token = 'token';
|
||||
const OAuth2Protocol_ResponseType = 'response_type';
|
||||
const OAuth2Protocol_ClientId = 'client_id';
|
||||
const OAuth2Protocol_ClientSecret = "client_secret";
|
||||
const OAuth2Protocol_AccessToken = "access_token";
|
||||
const OAuth2Protocol_Token = "token";
|
||||
@ -121,11 +123,13 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
|
||||
//todo: add dynamic creation logic (configure grants types from db)
|
||||
|
||||
$authorization_code_grant_type = new AuthorizationCodeGrantType($scope_service,$client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service);
|
||||
$authorization_code_grant_type = new AuthorizationCodeGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service);
|
||||
$implicit_grant_type = new ImplicitGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service);
|
||||
$validate_bearer_token_grant_type = new ValidateBearerTokenGrantType($client_service, $token_service, $log_service);
|
||||
$refresh_bearer_token_grant_type = new RefreshBearerTokenGrantType($client_service,$token_service,$log_service);
|
||||
|
||||
$this->grant_types[$authorization_code_grant_type->getType()] = $authorization_code_grant_type;
|
||||
$this->grant_types[$implicit_grant_type->getType()] = $implicit_grant_type;
|
||||
$this->grant_types[$validate_bearer_token_grant_type->getType()] = $validate_bearer_token_grant_type;
|
||||
$this->grant_types[$refresh_bearer_token_grant_type->getType()] = $refresh_bearer_token_grant_type;
|
||||
|
||||
@ -143,7 +147,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
* @throws \Exception
|
||||
* @throws exceptions\UriNotAllowedException
|
||||
*/
|
||||
public function authorize(OAuth2Request $request)
|
||||
public function authorize(OAuth2Request $request = null)
|
||||
{
|
||||
try {
|
||||
if (is_null($request) || !$request->isValid())
|
||||
@ -152,12 +156,11 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
} catch (InvalidOAuth2Request $ex1) {
|
||||
$this->log_service->error($ex1);
|
||||
$this->checkpoint_service->trackException($ex1);
|
||||
|
||||
$redirect_uri = $this->validateRedirectUri($request);
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex1;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest, $redirect_uri);
|
||||
} catch (UnsupportedResponseTypeException $ex2) {
|
||||
$this->log_service->error($ex2);
|
||||
$this->checkpoint_service->trackException($ex2);
|
||||
@ -166,7 +169,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex2;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnsupportedResponseType, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_UnsupportedResponseType, $redirect_uri);
|
||||
} catch (InvalidClientException $ex3) {
|
||||
$this->log_service->error($ex3);
|
||||
$this->checkpoint_service->trackException($ex3);
|
||||
@ -175,12 +178,13 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex3;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
|
||||
} catch (UriNotAllowedException $ex4) {
|
||||
$this->log_service->error($ex4);
|
||||
$this->checkpoint_service->trackException($ex4);
|
||||
throw $ex4;
|
||||
} catch (ScopeNotAllowedException $ex5) {
|
||||
|
||||
$this->log_service->error($ex5);
|
||||
$this->checkpoint_service->trackException($ex5);
|
||||
|
||||
@ -188,7 +192,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex5;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_InvalidScope, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_InvalidScope, $redirect_uri);
|
||||
} catch (UnAuthorizedClientException $ex6) {
|
||||
$this->log_service->error($ex6);
|
||||
$this->checkpoint_service->trackException($ex6);
|
||||
@ -197,7 +201,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex6;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
|
||||
} catch (AccessDeniedException $ex7) {
|
||||
$this->log_service->error($ex7);
|
||||
$this->checkpoint_service->trackException($ex7);
|
||||
@ -206,7 +210,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex7;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_AccessDenied, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_AccessDenied, $redirect_uri);
|
||||
} catch (OAuth2GenericException $ex8) {
|
||||
$this->log_service->error($ex8);
|
||||
$this->checkpoint_service->trackException($ex8);
|
||||
@ -215,7 +219,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex8;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri);
|
||||
} catch (Exception $ex) {
|
||||
$this->log_service->error($ex);
|
||||
$this->checkpoint_service->trackException($ex);
|
||||
@ -224,19 +228,21 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
if (is_null($redirect_uri))
|
||||
throw $ex;
|
||||
|
||||
return new OAuth2IndirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri);
|
||||
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request,OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateRedirectUri(OAuth2Request $request)
|
||||
private function validateRedirectUri(OAuth2Request $request = null)
|
||||
{
|
||||
if(is_null($request))
|
||||
return null;
|
||||
$redirect_uri = $request->getRedirectUri();
|
||||
if (is_null($redirect_uri))
|
||||
return null;
|
||||
$client_id = $request->getClientId();
|
||||
if (is_null($client_id))
|
||||
return null;
|
||||
$client = $this->client_service->getClientByIdentifier($client_id);
|
||||
$client = $this->client_service->getClientById($client_id);
|
||||
if (is_null($client))
|
||||
return null;
|
||||
if (!$client->isUriAllowed($redirect_uri))
|
||||
@ -248,7 +254,7 @@ class OAuth2Protocol implements IOAuth2Protocol
|
||||
* @param OAuth2Request $request
|
||||
* @return OAuth2DirectErrorResponse|void
|
||||
*/
|
||||
public function token(OAuth2Request $request)
|
||||
public function token(OAuth2Request $request = null)
|
||||
{
|
||||
try {
|
||||
if (is_null($request) || !$request->isValid())
|
||||
|
@ -10,6 +10,12 @@ use oauth2\exceptions\InvalidGrantTypeException;
|
||||
/**
|
||||
* Class AuthorizationEndpoint
|
||||
* Authorization Endpoint Implementation
|
||||
* The authorization endpoint is used to interact with the resource
|
||||
* owner and obtain an authorization grant. The authorization server
|
||||
* MUST first verify the identity of the resource owner. The way in
|
||||
* which the authorization server authenticates the resource owner
|
||||
* (e.g., username and password login, session cookies) is beyond the
|
||||
* scope of this specification.
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.1
|
||||
* @package oauth2\endpoints
|
||||
*/
|
||||
|
@ -11,6 +11,10 @@ use oauth2\requests\OAuth2Request;
|
||||
/**
|
||||
* Class TokenEndpoint
|
||||
* Token Endpoint Implementation
|
||||
* The token endpoint is used by the client to obtain an access token by
|
||||
* presenting its authorization grant or refresh token. The token
|
||||
* endpoint is used with every authorization grant except for the
|
||||
* implicit grant type (since an access token is issued directly).
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.2
|
||||
* @package oauth2\endpoints
|
||||
*/
|
||||
|
@ -33,13 +33,17 @@ use utils\services\ILogService;
|
||||
/**
|
||||
* Class AuthorizationCodeGrantType
|
||||
* Authorization Code Grant Implementation
|
||||
* The authorization code grant type is used to obtain both access
|
||||
* tokens and refresh tokens and is optimized for confidential clients.
|
||||
* Since this is a redirection-based flow, the client must be capable of
|
||||
* interacting with the resource owner's user-agent (typically a web
|
||||
* browser) and capable of receiving incoming requests (via redirection)
|
||||
* from the authorization server.
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1
|
||||
* @package oauth2\grant_types
|
||||
*/
|
||||
class AuthorizationCodeGrantType extends AbstractGrantType
|
||||
{
|
||||
|
||||
|
||||
private $auth_service;
|
||||
private $auth_strategy;
|
||||
private $memento_service;
|
||||
@ -59,7 +63,7 @@ class AuthorizationCodeGrantType extends AbstractGrantType
|
||||
$reflector = new ReflectionClass($request);
|
||||
$class_name = $reflector->getName();
|
||||
return
|
||||
($class_name == 'oauth2\requests\OAuth2AuthorizationRequest' && $request->isValid()) ||
|
||||
($class_name == 'oauth2\requests\OAuth2AuthorizationRequest' && $request->isValid() && $request->getResponseType() === $this->getResponseType()) ||
|
||||
($class_name == 'oauth2\requests\OAuth2TokenRequest' && $request->isValid() && $request->getGrantType() === $this->getType());
|
||||
}
|
||||
|
||||
@ -88,7 +92,8 @@ class AuthorizationCodeGrantType extends AbstractGrantType
|
||||
$reflector = new ReflectionClass($request);
|
||||
$class_name = $reflector->getName();
|
||||
if ($class_name == 'oauth2\requests\OAuth2AuthorizationRequest') {
|
||||
$client_id = $request->getClientId();
|
||||
|
||||
$client_id = $request->getClientId();
|
||||
|
||||
$response_type = $request->getResponseType();
|
||||
|
||||
@ -126,26 +131,14 @@ class AuthorizationCodeGrantType extends AbstractGrantType
|
||||
} else if ($authorization_response === IAuthService::AuthorizationResponse_DenyOnce) {
|
||||
throw new AccessDeniedException;
|
||||
}
|
||||
$response = new OAuth2AuthorizationResponse();
|
||||
// build current audience ...
|
||||
$audiences = $this->scope_service->getAudienceByScopeNames(explode(' ',$scope));
|
||||
$audience = '';
|
||||
foreach($audiences as $resource_server_host => $ip){
|
||||
$audience = $audience . $resource_server_host .' ';
|
||||
}
|
||||
$audience = trim($audience);
|
||||
$audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope));
|
||||
|
||||
$auth_code = $this->token_service->createAuthorizationCode($client_id, $scope, $audience, $redirect_uri);
|
||||
|
||||
if (is_null($auth_code))
|
||||
throw new OAuth2GenericException("Invalid Auth Code");
|
||||
|
||||
$response->setAuthorizationCode($auth_code->getValue());
|
||||
$response->setReturnTo($redirect_uri);
|
||||
//if state is present, return it on response
|
||||
if (!is_null($state))
|
||||
$response->setState($state);
|
||||
return $response;
|
||||
return new OAuth2AuthorizationResponse($redirect_uri, $auth_code->getValue(), $state);
|
||||
}
|
||||
throw new InvalidOAuth2Request;
|
||||
}
|
||||
|
166
app/libs/oauth2/grant_types/ImplicitGrantType.php
Normal file
166
app/libs/oauth2/grant_types/ImplicitGrantType.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace oauth2\grant_types;
|
||||
|
||||
use oauth2\exceptions\AccessDeniedException;
|
||||
use oauth2\exceptions\InvalidClientException;
|
||||
use oauth2\exceptions\InvalidOAuth2Request;
|
||||
use oauth2\exceptions\ScopeNotAllowedException;
|
||||
use oauth2\exceptions\UnAuthorizedClientException;
|
||||
|
||||
use oauth2\exceptions\UnsupportedResponseTypeException;
|
||||
use oauth2\exceptions\UriNotAllowedException;
|
||||
use oauth2\models\IClient;
|
||||
use oauth2\OAuth2Protocol;
|
||||
use oauth2\requests\OAuth2Request;
|
||||
|
||||
use oauth2\responses\OAuth2AccessTokenFragmentResponse;
|
||||
use oauth2\services\IApiScopeService;
|
||||
use oauth2\services\IClientService;
|
||||
use oauth2\services\ITokenService;
|
||||
use oauth2\services\IMementoOAuth2AuthenticationRequestService;
|
||||
|
||||
use oauth2\strategies\IOAuth2AuthenticationStrategy;
|
||||
use ReflectionClass;
|
||||
use utils\services\IAuthService;
|
||||
use utils\services\ILogService;
|
||||
|
||||
/**
|
||||
* Class ImplicitGrantType
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.2
|
||||
* The implicit grant type is used to obtain access tokens (it does not
|
||||
* support the issuance of refresh tokens) and is optimized for public
|
||||
* clients known to operate a particular redirection URI. These clients
|
||||
* are typically implemented in a browser using a scripting language
|
||||
* such as JavaScript.
|
||||
* Since this is a redirection-based flow, the client must be capable of
|
||||
* interacting with the resource owner's user-agent (typically a web
|
||||
* browser) and capable of receiving incoming requests (via redirection)
|
||||
* from the authorization server.
|
||||
* Unlike the authorization code grant type, in which the client makes
|
||||
* separate requests for authorization and for an access token, the
|
||||
* client receives the access token as the result of the authorization
|
||||
* request.
|
||||
* The implicit grant type does not include client authentication, and
|
||||
* relies on the presence of the resource owner and the registration of
|
||||
* the redirection URI. Because the access token is encoded into the
|
||||
* redirection URI, it may be exposed to the resource owner and other
|
||||
* applications residing on the same device.
|
||||
* @package oauth2\grant_types
|
||||
*/
|
||||
class ImplicitGrantType extends AbstractGrantType
|
||||
{
|
||||
|
||||
private $auth_service;
|
||||
private $auth_strategy;
|
||||
private $scope_service;
|
||||
|
||||
public function __construct(IApiScopeService $scope_service, IClientService $client_service, ITokenService $token_service, IAuthService $auth_service, IMementoOAuth2AuthenticationRequestService $memento_service, IOAuth2AuthenticationStrategy $auth_strategy, ILogService $log_service)
|
||||
{
|
||||
parent::__construct($client_service, $token_service, $log_service);
|
||||
$this->scope_service = $scope_service;
|
||||
$this->auth_service = $auth_service;
|
||||
$this->memento_service = $memento_service;
|
||||
$this->auth_strategy = $auth_strategy;
|
||||
}
|
||||
|
||||
/** Given an OAuth2Request, returns true if it can handle it, false otherwise
|
||||
* @param OAuth2Request $request
|
||||
* @return boolean
|
||||
*/
|
||||
public function canHandle(OAuth2Request $request)
|
||||
{
|
||||
$reflector = new ReflectionClass($request);
|
||||
$class_name = $reflector->getName();
|
||||
return
|
||||
($class_name == 'oauth2\requests\OAuth2AuthorizationRequest' && $request->isValid() && $request->getResponseType() === $this->getResponseType());
|
||||
}
|
||||
|
||||
/** get grant type response type
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponseType()
|
||||
{
|
||||
return OAuth2Protocol::OAuth2Protocol_ResponseType_Token;
|
||||
}
|
||||
|
||||
/** defines entry point for first request processing
|
||||
* @param OAuth2Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(OAuth2Request $request)
|
||||
{
|
||||
$reflector = new ReflectionClass($request);
|
||||
$class_name = $reflector->getName();
|
||||
if ($class_name == 'oauth2\requests\OAuth2AuthorizationRequest') {
|
||||
|
||||
$client_id = $request->getClientId();
|
||||
|
||||
$response_type = $request->getResponseType();
|
||||
|
||||
if ($response_type !== $this->getResponseType())
|
||||
throw new UnsupportedResponseTypeException(sprintf("response_type %s", $response_type));
|
||||
|
||||
$client = $this->client_service->getClientById($client_id);
|
||||
if (is_null($client))
|
||||
throw new InvalidClientException(sprintf("client_id %s", $client_id));
|
||||
|
||||
//check client type
|
||||
if ($client->getClientType() !== IClient::ClientType_Public)
|
||||
throw new UnAuthorizedClientException();
|
||||
|
||||
//check redirect uri
|
||||
$redirect_uri = $request->getRedirectUri();
|
||||
if (!$client->isUriAllowed($redirect_uri))
|
||||
throw new UriNotAllowedException(sprintf("redirect_to %s", $redirect_uri));
|
||||
|
||||
//check requested scope
|
||||
$scope = $request->getScope();
|
||||
|
||||
if (is_null($scope) || empty($scope) || !$client->isScopeAllowed($scope))
|
||||
throw new ScopeNotAllowedException(sprintf("redirect_to %s", $redirect_uri));
|
||||
|
||||
$state = $request->getState();
|
||||
//check user logged
|
||||
if (!$this->auth_service->isUserLogged()) {
|
||||
$this->memento_service->saveCurrentAuthorizationRequest();
|
||||
return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest());
|
||||
}
|
||||
|
||||
//validate authorization
|
||||
$authorization_response = $this->auth_service->getUserAuthorizationResponse();
|
||||
if ($authorization_response === IAuthService::AuthorizationResponse_None) {
|
||||
$this->memento_service->saveCurrentAuthorizationRequest();
|
||||
return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest());
|
||||
} else if ($authorization_response === IAuthService::AuthorizationResponse_DenyOnce) {
|
||||
throw new AccessDeniedException;
|
||||
}
|
||||
|
||||
// build current audience ...
|
||||
$audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope));
|
||||
//build access token
|
||||
$access_token = $this->token_service->createAccessTokenFromParams($scope, $client_id, $audience);
|
||||
|
||||
return new OAuth2AccessTokenFragmentResponse($redirect_uri, $access_token->getValue(), $access_token->getLifetime(), $scope, $state);
|
||||
}
|
||||
throw new InvalidOAuth2Request;
|
||||
}
|
||||
|
||||
/**
|
||||
* get grant type
|
||||
* @return mixed
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return OAuth2Protocol::OAuth2Protocol_GrantType_Implicit;
|
||||
}
|
||||
|
||||
/** builds specific Token request
|
||||
* @param OAuth2Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function buildTokenRequest(OAuth2Request $request)
|
||||
{
|
||||
throw new \Exception('not implemented!!');
|
||||
}
|
||||
}
|
@ -28,6 +28,17 @@ class AccessToken extends Token {
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public static function createFromParams($scope, $client_id, $audience,$lifetime){
|
||||
$instance = new self();
|
||||
$instance->value = Rand::getString($instance->len,null,true);
|
||||
$instance->scope = $scope;
|
||||
$instance->client_id = $client_id;
|
||||
$instance->auth_code = null;
|
||||
$instance->audience = $audience;
|
||||
$instance->lifetime = $lifetime;
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public static function createFromRefreshToken(RefreshToken $refresh_token,$scope = null, $lifetime = 3600){
|
||||
$instance = new self();
|
||||
$instance->value = Rand::getString($instance->len,null,true);
|
||||
|
@ -7,6 +7,23 @@ use Zend\Math\Rand;
|
||||
/**
|
||||
* Class RefreshToken
|
||||
* http://tools.ietf.org/html/rfc6749#section-1.5
|
||||
*
|
||||
* The refresh token is also a secret bound to the client identifier and
|
||||
* client instance that originally requested the authorization; the
|
||||
* refresh token also represents the original resource owner grant.
|
||||
* This is ensured by the authorization process as follows:
|
||||
* 1. The resource owner and user agent safely deliver the
|
||||
* authorization "code" to the client instance in the first place.
|
||||
* 2. The client uses it immediately in secure transport-level
|
||||
* communications to the authorization server and then securely
|
||||
* stores the long-lived refresh token.
|
||||
* 3. The client always uses the refresh token in secure transport-
|
||||
* level communications to the authorization server to get an access
|
||||
* token (and optionally roll over the refresh token).
|
||||
* So, as long as the confidentiality of the particular token can be
|
||||
* ensured by the client, a refresh token can also be used as an
|
||||
* alternative means to authenticate the client instance itself.
|
||||
* from http://tools.ietf.org/html/rfc6819#section-3.3
|
||||
* @package oauth2\models
|
||||
*/
|
||||
class RefreshToken extends Token {
|
||||
|
@ -56,9 +56,6 @@ class OAuth2AuthorizationRequest extends OAuth2Request {
|
||||
if(is_null($this->getRedirectUri()))
|
||||
return false;
|
||||
|
||||
if(is_null($this->getScope()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace oauth2\responses;
|
||||
|
||||
use oauth2\OAuth2Protocol;
|
||||
|
||||
class OAuth2AccessTokenFragmentResponse extends OAuth2IndirectFragmentResponse {
|
||||
|
||||
public function __construct($return_to, $access_token, $expires_in, $scope=null, $state=null)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->setReturnTo($return_to);
|
||||
|
||||
$this[OAuth2Protocol::OAuth2Protocol_AccessToken] = $access_token;
|
||||
$this[OAuth2Protocol::OAuth2Protocol_AccessToken_ExpiresIn] = $expires_in;
|
||||
$this[OAuth2Protocol::OAuth2Protocol_TokenType] = 'Bearer';
|
||||
|
||||
if(!is_null($scope) && !empty($scope))
|
||||
$this[OAuth2Protocol::OAuth2Protocol_Scope] = $scope;
|
||||
|
||||
if(!is_null($state) && !empty($state))
|
||||
$this[OAuth2Protocol::OAuth2Protocol_State] = $state;
|
||||
}
|
||||
}
|
@ -10,12 +10,14 @@ use oauth2\OAuth2Protocol;
|
||||
*/
|
||||
class OAuth2AuthorizationResponse extends OAuth2IndirectResponse {
|
||||
|
||||
public function setAuthorizationCode($code){
|
||||
$this[OAuth2Protocol::OAuth2Protocol_ResponseType_Code] = $code;
|
||||
}
|
||||
|
||||
public function setState($state){
|
||||
$this[OAuth2Protocol::OAuth2Protocol_State] = $state;
|
||||
public function __construct($return_url, $code, $state=null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this[OAuth2Protocol::OAuth2Protocol_ResponseType_Code] = $code;
|
||||
$this->setReturnTo($return_url);
|
||||
if(!is_null($state))
|
||||
$this[OAuth2Protocol::OAuth2Protocol_State] = $state;
|
||||
}
|
||||
|
||||
}
|
@ -7,8 +7,8 @@ use oauth2\OAuth2Protocol;
|
||||
class OAuth2DirectErrorResponse extends OAuth2DirectResponse {
|
||||
public function __construct($error)
|
||||
{
|
||||
// Successful Responses: A server receiving a valid request MUST send a
|
||||
// response with an HTTP status code of 200.
|
||||
// Error Response: A server receiving an invalid request MUST send a
|
||||
// response with an HTTP status code of 400.
|
||||
parent::__construct(self::HttpErrorResponse, self::DirectResponseContentType);
|
||||
$this[OAuth2Protocol::OAuth2Protocol_Error] = $error;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ namespace oauth2\responses;
|
||||
class OAuth2DirectResponse extends OAuth2Response {
|
||||
|
||||
const DirectResponseContentType = "application/json;charset=UTF-8";
|
||||
const OAuth2DirectResponse ='OAuth2DirectResponse';
|
||||
const OAuth2DirectResponse = 'OAuth2DirectResponse';
|
||||
|
||||
public function __construct($http_code=self::HttpOkResponse, $content_type=self::DirectResponseContentType)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ use openid\responses\OpenIdIndirectResponse;
|
||||
|
||||
class OAuth2IndirectErrorResponse extends OAuth2IndirectResponse {
|
||||
|
||||
public function __construct($error,$return_to=null){
|
||||
public function __construct($error, $return_to=null){
|
||||
$this[OAuth2Protocol::OAuth2Protocol_Error] = $error;
|
||||
$this->return_to = $return_to;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace oauth2\responses;
|
||||
|
||||
use oauth2\OAuth2Protocol;
|
||||
|
||||
class OAuth2IndirectFragmentErrorResponse extends OAuth2IndirectFragmentResponse {
|
||||
|
||||
public function __construct($error, $return_to=null){
|
||||
parent::__construct();
|
||||
$this->setError($error);
|
||||
$this->setReturnTo($return_to);
|
||||
}
|
||||
|
||||
public function setError($error){
|
||||
$this[OAuth2Protocol::OAuth2Protocol_Error] = $error;
|
||||
}
|
||||
|
||||
}
|
18
app/libs/oauth2/responses/OAuth2IndirectFragmentResponse.php
Normal file
18
app/libs/oauth2/responses/OAuth2IndirectFragmentResponse.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace oauth2\responses;
|
||||
|
||||
|
||||
class OAuth2IndirectFragmentResponse extends OAuth2IndirectResponse {
|
||||
|
||||
const OAuth2IndirectFragmentResponse ='OAuth2IndirectFragmentResponse';
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return self::OAuth2IndirectFragmentResponse;
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ abstract class OAuth2IndirectResponse extends OAuth2Response {
|
||||
protected $return_to;
|
||||
|
||||
const IndirectResponseContentType = "application/x-www-form-urlencoded";
|
||||
const OAuth2IndirectResponse ='OAuth2IndirectResponse';
|
||||
const OAuth2IndirectResponse ='OAuth2IndirectResponse';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -14,4 +14,6 @@ interface IApiScopeService {
|
||||
public function getAvailableScopes();
|
||||
|
||||
public function getAudienceByScopeNames(array $scopes_names);
|
||||
|
||||
public function getStrAudienceByScopeNames(array $scopes_names);
|
||||
}
|
@ -38,6 +38,15 @@ interface ITokenService {
|
||||
public function createAccessToken(AuthorizationCode $auth_code,$redirect_uri=null);
|
||||
|
||||
|
||||
/**
|
||||
* @param $scope
|
||||
* @param $client_id
|
||||
* @param $audience
|
||||
* @return mixed
|
||||
*/
|
||||
public function createAccessTokenFromParams($scope, $client_id, $audience);
|
||||
|
||||
|
||||
/** Creates a new Access Token from a given refresh token, and invalidate former associated
|
||||
* Access Token
|
||||
* @param RefreshToken $refresh_token
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace oauth2\strategies;
|
||||
|
||||
use oauth2\requests\OAuth2Request;
|
||||
use oauth2\responses\OAuth2IndirectErrorResponse;
|
||||
use oauth2\responses\OAuth2IndirectFragmentErrorResponse;
|
||||
use oauth2\responses\OAuth2IndirectResponse;
|
||||
use oauth2\OAuth2Protocol;
|
||||
use ReflectionClass;
|
||||
|
||||
class OAuth2IndirectErrorResponseFactoryMethod {
|
||||
|
||||
/**
|
||||
* @param OAuth2Request $request
|
||||
* @param $error
|
||||
* @param $return_url
|
||||
* @return OAuth2IndirectResponse
|
||||
*/
|
||||
public static function buildResponse(OAuth2Request $request = null,$error, $return_url){
|
||||
$response = null;
|
||||
$reflector = new ReflectionClass($request);
|
||||
$class_name = $reflector->getName();
|
||||
if($class_name ==='oauth2\requests\OAuth2AuthorizationRequest'){
|
||||
$response_type = $request->getResponseType();
|
||||
switch($response_type){
|
||||
case OAuth2Protocol::OAuth2Protocol_ResponseType_Token:
|
||||
return new OAuth2IndirectFragmentErrorResponse($error,$return_url);
|
||||
break;
|
||||
case OAuth2Protocol::OAuth2Protocol_ResponseType_Code:
|
||||
return new OAuth2IndirectErrorResponse($error,$return_url);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(sprintf("invalid response type %s",$response_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace oauth2\strategies;
|
||||
|
||||
use oauth2\responses\OAuth2DirectResponse;
|
||||
use oauth2\responses\OAuth2IndirectFragmentResponse;
|
||||
use oauth2\responses\OAuth2IndirectResponse;
|
||||
use oauth2\responses\OAuth2Response;
|
||||
use utils\services\Registry;
|
||||
@ -18,6 +19,13 @@ class OAuth2ResponseStrategyFactoryMethod {
|
||||
return Registry::getInstance()->get(OAuth2IndirectResponse::OAuth2IndirectResponse);
|
||||
}
|
||||
break;
|
||||
|
||||
case OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse:
|
||||
{
|
||||
return Registry::getInstance()->get(OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse);
|
||||
}
|
||||
break;
|
||||
|
||||
case OAuth2DirectResponse::OAuth2DirectResponse:
|
||||
{
|
||||
return Registry::getInstance()->get(OAuth2DirectResponse::OAuth2DirectResponse);
|
||||
|
@ -1,6 +1,11 @@
|
||||
<?php
|
||||
namespace utils;
|
||||
|
||||
/**
|
||||
* Interface IHttpResponseStrategy
|
||||
* Defines an interface to handle http responses
|
||||
* @package utils
|
||||
*/
|
||||
interface IHttpResponseStrategy {
|
||||
public function handle($response);
|
||||
}
|
@ -46,5 +46,15 @@ class ApiScopeService implements IApiScopeService {
|
||||
return $audience;
|
||||
}
|
||||
|
||||
public function getStrAudienceByScopeNames(array $scopes_names){
|
||||
$audiences = $this->getAudienceByScopeNames($scopes_names);
|
||||
$audience = '';
|
||||
foreach($audiences as $resource_server_host => $ip){
|
||||
$audience = $audience . $resource_server_host .' ';
|
||||
}
|
||||
$audience = trim($audience);
|
||||
return $audience;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,6 +22,8 @@ use oauth2\services\OAuth2ServiceCatalog;
|
||||
class ClientService implements IClientService
|
||||
{
|
||||
|
||||
const PrintableNonWhitespaceCharactersUrl = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~.-_';
|
||||
|
||||
private $auth_service;
|
||||
|
||||
public function __construct(IAuthService $auth_service)
|
||||
@ -79,10 +81,10 @@ class ClientService implements IClientService
|
||||
$client = new Client;
|
||||
$client->app_name = $app_name;
|
||||
$client->app_logo = $app_logo;
|
||||
$client->client_id = Rand::getString(32) . '.openstack.client';
|
||||
$client->client_id = Rand::getString(32, self::PrintableNonWhitespaceCharactersUrl,true) . '.openstack.client';
|
||||
//only generates secret for confidential clients
|
||||
if($client_type==IClient::ClientType_Confidential)
|
||||
$client->client_secret = Rand::getString(16);
|
||||
$client->client_secret = Rand::getString(16, self::PrintableNonWhitespaceCharactersUrl,true);
|
||||
$client->client_type = $client_type;
|
||||
$client->user_id = $user_id;
|
||||
$client->active = true;
|
||||
@ -168,7 +170,7 @@ class ClientService implements IClientService
|
||||
|
||||
$client = Client::find($id);
|
||||
if (!is_null($client)) {
|
||||
$client_secret = Rand::getString(16);
|
||||
$client_secret = Rand::getString(16, self::PrintableNonWhitespaceCharactersUrl,true);
|
||||
$client->client_secret = $client_secret;
|
||||
$client->Save();
|
||||
$token_service = Registry::getInstance()->get(OAuth2ServiceCatalog::TokenService);
|
||||
|
@ -64,7 +64,7 @@ class MementoOAuth2AuthenticationRequestService implements IMementoOAuth2Authent
|
||||
}
|
||||
}
|
||||
if (count($oauth2_params) > 0) {
|
||||
$msg = new OAuth2AuthorizationRequest($oauth2_params);
|
||||
$msg = new OAuth2AuthorizationRequest(new OAuth2Message($oauth2_params));
|
||||
}
|
||||
}
|
||||
return $msg;
|
||||
|
@ -121,16 +121,14 @@ class TokenService implements ITokenService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $auth_code
|
||||
* @param $client_id
|
||||
* @param $scope
|
||||
* @param AuthorizationCode $auth_code
|
||||
* @param null $redirect_uri
|
||||
* @return Token
|
||||
* @return AccessToken
|
||||
*/
|
||||
public function createAccessToken(AuthorizationCode $auth_code, $redirect_uri = null)
|
||||
{
|
||||
$access_token = AccessToken::create($auth_code, $this->configuration_service->getConfigValue('OAuth2.AccessToken.Lifetime'));
|
||||
$value = $access_token->getValue();
|
||||
$value = $access_token->getValue();
|
||||
$hashed_value = Hash::compute('sha256', $value);
|
||||
|
||||
$this->storesAccessTokenOnRedis($access_token);
|
||||
@ -154,6 +152,32 @@ class TokenService implements ITokenService
|
||||
return $access_token;
|
||||
}
|
||||
|
||||
public function createAccessTokenFromParams($scope, $client_id, $audience){
|
||||
$access_token = AccessToken::createFromParams($scope, $client_id, $audience, $this->configuration_service->getConfigValue('OAuth2.AccessToken.Lifetime'));
|
||||
$value = $access_token->getValue();
|
||||
$hashed_value = Hash::compute('sha256', $value);
|
||||
|
||||
$this->storesAccessTokenOnRedis($access_token);
|
||||
|
||||
$client_id = $access_token->getClientId();
|
||||
$client = $this->client_service->getClientById($client_id);
|
||||
|
||||
//stores in DB
|
||||
$access_token_db = new DBAccessToken;
|
||||
$access_token_db->value = $hashed_value;
|
||||
$access_token_db->from_ip = IPHelper::getUserIp();
|
||||
$access_token_db->associated_authorization_code = null;
|
||||
$access_token_db->lifetime = $access_token->getLifetime();
|
||||
$access_token_db->scope = $access_token->getScope();
|
||||
$access_token_db->client_id = $client->getId();
|
||||
$access_token_db->audience = $access_token->getAudience();
|
||||
$access_token_db->Save();
|
||||
|
||||
//stores brand new access token hash value on a set by client id...
|
||||
$this->redis->sadd($client_id . self::ClientAccessTokenPrefixList, $hashed_value);
|
||||
return $access_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccessToken $access_token
|
||||
* @throws \oauth2\exceptions\InvalidAccessTokenException
|
||||
|
@ -7,13 +7,23 @@ use utils\IHttpResponseStrategy;
|
||||
use Redirect;
|
||||
use Response;
|
||||
|
||||
class IndirectResponseStrategy implements IHttpResponseStrategy
|
||||
/**
|
||||
* Class IndirectResponseQueryStringStrategy
|
||||
* Redirect and http response using a 302 adding params on query string
|
||||
* @package strategies
|
||||
*/
|
||||
class IndirectResponseQueryStringStrategy implements IHttpResponseStrategy
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $response
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($response)
|
||||
{
|
||||
$query_string = $response->getContent();
|
||||
$return_to = $response->getReturnTo();
|
||||
$return_to = $response->getReturnTo();
|
||||
|
||||
if (is_null($return_to) || empty($return_to)) {
|
||||
return \View::make('404');
|
||||
}
|
33
app/strategies/IndirectResponseUrlFragmentStrategy.php
Normal file
33
app/strategies/IndirectResponseUrlFragmentStrategy.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace strategies;
|
||||
|
||||
use utils\IHttpResponseStrategy;
|
||||
use Redirect;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* Class IndirectResponseUrlFragmentStrategy
|
||||
* Redirect and http response using a 302 adding params on url fragment
|
||||
* @package strategies
|
||||
*/
|
||||
class IndirectResponseUrlFragmentStrategy implements IHttpResponseStrategy
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $response
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($response)
|
||||
{
|
||||
$fragment = $response->getContent();
|
||||
$return_to = $response->getReturnTo();
|
||||
|
||||
if (is_null($return_to) || empty($return_to)) {
|
||||
return \View::make('404');
|
||||
}
|
||||
|
||||
$return_to = (strpos($return_to, "#") === false) ? $return_to . "#" . $fragment : $return_to . "&" . $fragment;
|
||||
return Redirect::to($return_to);
|
||||
}
|
||||
}
|
@ -8,19 +8,20 @@ use oauth2\responses\OAuth2IndirectResponse;
|
||||
use openid\responses\OpenIdDirectResponse;
|
||||
use openid\responses\OpenIdIndirectResponse;
|
||||
use utils\services\Registry;
|
||||
use oauth2\responses\OAuth2IndirectFragmentResponse;
|
||||
|
||||
class StrategyProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
|
||||
public function boot()
|
||||
{
|
||||
//direct response strategy
|
||||
$this->app->singleton(OAuth2DirectResponse::OAuth2DirectResponse, 'strategies\\DirectResponseStrategy');
|
||||
$this->app->singleton(OpenIdDirectResponse::OpenIdDirectResponse, 'strategies\\DirectResponseStrategy');
|
||||
//indirect response strategy
|
||||
$this->app->singleton(OpenIdIndirectResponse::OpenIdIndirectResponse, 'strategies\\IndirectResponseStrategy');
|
||||
$this->app->singleton(OAuth2IndirectResponse::OAuth2IndirectResponse, 'strategies\\IndirectResponseStrategy');
|
||||
$this->app->singleton(OpenIdIndirectResponse::OpenIdIndirectResponse, 'strategies\\IndirectResponseQueryStringStrategy');
|
||||
$this->app->singleton(OAuth2IndirectResponse::OAuth2IndirectResponse, 'strategies\\IndirectResponseQueryStringStrategy');
|
||||
$this->app->singleton(OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse,'strategies\\IndirectResponseUrlFragmentStrategy');
|
||||
|
||||
$this->app->singleton('oauth2\\strategies\\IOAuth2AuthenticationStrategy', 'strategies\\OAuth2AuthenticationStrategy');
|
||||
|
||||
@ -29,6 +30,7 @@ class StrategyProvider extends ServiceProvider
|
||||
|
||||
Registry::getInstance()->set(OpenIdIndirectResponse::OpenIdIndirectResponse, $this->app->make(OpenIdIndirectResponse::OpenIdIndirectResponse));
|
||||
Registry::getInstance()->set(OAuth2IndirectResponse::OAuth2IndirectResponse, $this->app->make(OAuth2IndirectResponse::OAuth2IndirectResponse));
|
||||
Registry::getInstance()->set(OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse, $this->app->make(OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse));
|
||||
}
|
||||
|
||||
public function register()
|
||||
|
@ -37,9 +37,10 @@ class OAuth2TokenEndpointTest extends TestCase
|
||||
array(),
|
||||
array());
|
||||
|
||||
$status = $response->getStatusCode();
|
||||
$url = $response->getTargetUrl();
|
||||
$url = $response->getTargetUrl();
|
||||
$content = $response->getContent();
|
||||
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
/** Get Token Test
|
||||
@ -469,4 +470,47 @@ class OAuth2TokenEndpointTest extends TestCase
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
public function testImplicitFlow(){
|
||||
|
||||
$client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client';
|
||||
|
||||
//do login and consent ...
|
||||
$user = OpenIdUser::where('external_id', '=', 'smarcet@gmail.com')->first();
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
|
||||
|
||||
$params = array(
|
||||
'client_id' => $client_id,
|
||||
'redirect_uri' => 'https://www.test.com/oauth2',
|
||||
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token,
|
||||
'scope' => 'https://www.test.com/users/activities.read',
|
||||
'state' => '123456'
|
||||
);
|
||||
|
||||
$response = $this->action("POST", "OAuth2ProviderController@authorize",
|
||||
$params,
|
||||
array(),
|
||||
array(),
|
||||
array());
|
||||
|
||||
$this->assertResponseStatus(302);
|
||||
$url = $response->getTargetUrl();
|
||||
// get auth code ...
|
||||
$comps = @parse_url($url);
|
||||
$fragment = $comps['fragment'];
|
||||
$response = array();
|
||||
parse_str($fragment, $response);
|
||||
|
||||
$this->assertTrue(isset($response['access_token']) && !empty($response['access_token']));
|
||||
$this->assertTrue(isset($response['expires_in']));
|
||||
$this->assertTrue(isset($response['scope']));
|
||||
$this->assertTrue(isset($response['state']));
|
||||
$this->assertTrue($response['state']==='123456');
|
||||
$this->assertTrue(isset($response['token_type']));
|
||||
$this->assertTrue($response['token_type']==='Bearer');
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user