current_realm = Config::get('app.url'); Route::enableFilters(); Session::start(); } public function testNonePrompt() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_None ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('error', $output)); $this->assertTrue(!empty($output['error'])); $this->assertTrue($output['error'] === OAuth2Protocol::OAuth2Protocol_Error_Interaction_Required); } public function testLoginWithTrailingSpace() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => ' sebastian@tipit.net ', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_Display => OAuth2Protocol::OAuth2Protocol_Display_Native ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(412); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => ' sebastian@tipit.net ', 'password' => ' 1qaz2wsx ', '_token' => Session::token() ) ); $this->assertResponseStatus(302); } public function testConsentPrompt() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => IAuthService::AuthorizationResponse_DenyOnce, '_token' => Session::token() )); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('error', $output)); $this->assertTrue(!empty($output['error'])); $this->assertTrue($output['error'] === OAuth2Protocol::OAuth2Protocol_Error_Consent_Required); } public function testConsentLogin() { //already logged user $user = User::where('identifier', '=', 'sebastian.marcet')->first(); $this->be($user); $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Prompt => sprintf('%s %s', OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_Prompt_Login) ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => IAuthService::AuthorizationResponse_DenyOnce, '_token' => Session::token() )); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('error', $output)); $this->assertTrue(!empty($output['error'])); $this->assertTrue($output['error'] === OAuth2Protocol::OAuth2Protocol_Error_Consent_Required); } public function testAuthCode() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); } public function testAuthCodeInvalidLoginHint() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@sebastian.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $url = $response->getTargetUrl(); $this->assertTrue(str_contains($url, '/login')); } public function testAuthCodeOpenIdScopeOnly() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'scope' => 'openid', 'state' => 'KtWzJk5Vmk8CZwC0', 'redirect_uri' => 'https://op.certification.openid.net:60393/authz_cb', 'response_type' => 'code', 'client_id' => $client_id, ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); } public function testMaxAge1AndWait2() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 1 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); sleep(2); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $this->assertTrue($response->getTargetUrl() === URL::action("UserController@postLogin")); } public function testToken ( $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client', $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg', $use_enc = true ) { $params = array( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => sprintf('%s profile email address %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Nonce => 'test_nonce', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $jwt = BasicJWTFactory::build($id_token); if ($use_enc) { $this->assertTrue($jwt instanceof IJWE); $recipient_key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_1, RSAJWKPEMPrivateKeySpecification::WithoutPassword, $jwt->getJOSEHeader()->getAlgorithm()->getString() ) ); $recipient_key->setKeyUse(JSONWebKeyPublicKeyUseValues::Encryption)->setId('recipient_public_key'); $jwt->setRecipientKey($recipient_key); $payload = $jwt->getPlainText(); $jwt = BasicJWTFactory::build($payload); $this->assertTrue($jwt instanceof IJWS); } return $access_token; } public function testGetRefreshTokenWithPromptSetToConsentLogin(){ $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $use_enc = true; $params = array( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => sprintf('%s profile email address %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Nonce => 'test_nonce', OAuth2Protocol::OAuth2Protocol_Prompt => sprintf('%s %s',OAuth2Protocol::OAuth2Protocol_Prompt_Login, OAuth2Protocol::OAuth2Protocol_Prompt_Consent), OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $jwt = BasicJWTFactory::build($id_token); if ($use_enc) { $this->assertTrue($jwt instanceof IJWE); $recipient_key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_1, RSAJWKPEMPrivateKeySpecification::WithoutPassword, $jwt->getJOSEHeader()->getAlgorithm()->getString() ) ); $recipient_key->setKeyUse(JSONWebKeyPublicKeyUseValues::Encryption)->setId('recipient_public_key'); $jwt->setRecipientKey($recipient_key); $payload = $jwt->getPlainText(); $jwt = BasicJWTFactory::build($payload); $this->assertTrue($jwt instanceof IJWS); } } public function testFlowNativeDisplay(){ $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => sprintf('%s profile email address %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Nonce => 'test_nonce', OAuth2Protocol::OAuth2Protocol_Prompt => sprintf('%s %s',OAuth2Protocol::OAuth2Protocol_Prompt_Login, OAuth2Protocol::OAuth2Protocol_Prompt_Consent), OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Display => OAuth2Protocol::OAuth2Protocol_Display_Native ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $response = $this->call('GET', $response->getTargetUrl()); $this->assertResponseStatus(412); $json_response = json_decode($response->getContent(),true); // do login $response = $this->call($json_response['method'], $json_response['url'], array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => $json_response['required_params_valid_values']["_token"] ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(412); $json_response = json_decode($response->getContent(),true); $response = $this->call($json_response['method'], $json_response['url'], array( 'trust' => 'AllowOnce', '_token' => $json_response['required_params_valid_values']["_token"] )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); } public function testGetRefreshTokenFromNativeAppNTimes($n=5) { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.android.openstack.client'; $client_secret = '11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhgfdfdfdf'; $params_auth_code = array ( 'client_id' => $client_id, 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'response_type' => 'code', 'scope' => sprintf('%s profile email address %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Nonce => 'test_nonce', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params_auth_code, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $iteration = 0; do { $response = $this->action("POST", "OAuth2ProviderController@authorize", $params_auth_code, array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); ++$iteration; }while( $iteration < $n); } public function testTokenResponseModePost() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 1, OAuth2Protocol::OAuth2Protocol_ResponseMode => OAuth2Protocol::OAuth2Protocol_ResponseMode_FormPost ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(200); $content = $response->getContent(); $this->assertEquals('application/x-www-form-urlencoded', $response->headers->get('Content-Type')); $output = array(); parse_str($content, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $jwt = BasicJWTFactory::build($id_token); $this->assertTrue($jwt instanceof IJWE); $recipient_key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_1, RSAJWKPEMPrivateKeySpecification::WithoutPassword, $jwt->getJOSEHeader()->getAlgorithm()->getString() ) ); $recipient_key->setKeyUse(JSONWebKeyPublicKeyUseValues::Encryption)->setId('recipient_public_key'); $jwt->setRecipientKey($recipient_key); $payload = $jwt->getPlainText(); $jwt = BasicJWTFactory::build($payload); $this->assertTrue($jwt instanceof IJWS); $payload = $jwt->getPayload(); $claims_set = $payload->getClaimSet(); } public function testNativeClientBasicAuth() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.android.openstack.client'; $client_secret = '11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhgfdfdfdf'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'response_type' => 'code', 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 10000, OAuth2Protocol::OAuth2Protocol_ResponseMode => OAuth2Protocol::OAuth2Protocol_ResponseMode_FormPost ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(200); $content = $response->getContent(); $this->assertEquals('application/x-www-form-urlencoded', $response->headers->get('Content-Type')); $output = array(); parse_str($content, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $jwt = BasicJWTFactory::build($id_token); $this->assertTrue($jwt instanceof UnsecuredJWT); $claims_set = $jwt->getClaimSet(); $this->assertTrue(!is_null($claims_set)); $params = array( 'client_id' => $client_id, 'redirect_uri' => 'androipapp://oidc_endpoint_callback', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_IDTokenHint => $jwt->toCompactSerialization(), OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_None ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); } public function testClientAuthenticationClientSecretJwt() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x2.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $now = time(); $claim_set = JWTClaimSetFactory::build ( array ( RegisteredJWTClaimNames::Issuer => $client_id, RegisteredJWTClaimNames::Subject => $client_id, RegisteredJWTClaimNames::Audience => URL::action("OAuth2ProviderController@token"), RegisteredJWTClaimNames::JWTID => '123456789', RegisteredJWTClaimNames::ExpirationTime => $now + 3600, RegisteredJWTClaimNames::IssuedAt => $now ) ); $key = OctetSequenceJWKFactory::build ( new OctetSequenceJWKSpecification ( $client_secret, JSONWebSignatureAndEncryptionAlgorithms::HS512 ) ); $alg = new StringOrURI(JSONWebSignatureAndEncryptionAlgorithms::HS512); $jws = JWSFactory::build ( new JWS_ParamsSpecification ( $key, $alg, $claim_set ) ); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, OAuth2Protocol::OAuth2Protocol_ClientAssertionType => ClientAssertionAuthenticationContext::RegisteredAssertionType, OAuth2Protocol::OAuth2Protocol_ClientAssertion => $jws->toCompactSerialization() ); $response = $this->action ( "POST", "OAuth2ProviderController@token", $params, array(), array(), array() ); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $refresh_token = $response->refresh_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($refresh_token)); $this->assertTrue(!empty($id_token)); $jwt = BasicJWTFactory::build($id_token); $this->assertTrue($jwt instanceof IJWE); $recipient_key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_1, RSAJWKPEMPrivateKeySpecification::WithoutPassword, $jwt->getJOSEHeader()->getAlgorithm()->getString() ) ); $recipient_key->setKeyUse(JSONWebKeyPublicKeyUseValues::Encryption)->setId('recipient_public_key'); $jwt->setRecipientKey($recipient_key); $payload = $jwt->getPlainText(); $jwt = BasicJWTFactory::build($payload); $this->assertTrue($jwt instanceof IJWS); } public function testClientAuthenticationPrivateKeyJwt() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.android2.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'androipapp://oidc_endpoint_callback2', 'response_type' => 'code', 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200 ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $response = $this->action('GET', 'UserController@getConsent'); $this->assertResponseStatus(200); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $now = time(); $claim_set = JWTClaimSetFactory::build ( array ( RegisteredJWTClaimNames::Issuer => $client_id, RegisteredJWTClaimNames::Subject => $client_id, RegisteredJWTClaimNames::Audience => URL::action("OAuth2ProviderController@token"), RegisteredJWTClaimNames::JWTID => '123456789', RegisteredJWTClaimNames::ExpirationTime => $now + 3600, RegisteredJWTClaimNames::IssuedAt => $now ) ); $key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_2, RSAJWKPEMPrivateKeySpecification::WithoutPassword, JSONWebSignatureAndEncryptionAlgorithms::RS512 ) ); $key->setId('public_key_44'); $alg = new StringOrURI(JSONWebSignatureAndEncryptionAlgorithms::RS512); $jws = JWSFactory::build ( new JWS_ParamsSpecification ( $key, $alg, $claim_set ) ); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'androipapp://oidc_endpoint_callback2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, OAuth2Protocol::OAuth2Protocol_ClientAssertionType => ClientAssertionAuthenticationContext::RegisteredAssertionType, OAuth2Protocol::OAuth2Protocol_ClientAssertion => $jws->toCompactSerialization() ); $response = $this->action ( "POST", "OAuth2ProviderController@token", $params, array(), array(), array() ); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $id_token = $response->id_token; $this->assertTrue(!empty($access_token)); $this->assertTrue(!empty($id_token)); } public function testImplicitFlowTokenIdToken() { // use a public client $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_IdToken . OAuth2Protocol::OAuth2Protocol_ResponseType_Delimiter . OAuth2Protocol::OAuth2Protocol_ResponseType_Token, 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get response $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('access_token', $output)); $this->assertTrue(!empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); } public function testImplicitFlowIdToken() { // use a public client $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_IdToken, 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get response $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(!array_key_exists('access_token', $output)); $this->assertTrue(empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); } public function testImplicitFlowIdTokenMaxAge1000() { // use a public client $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_IdToken, 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 1000, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get response $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(!array_key_exists('access_token', $output)); $this->assertTrue(empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); sleep(10); $params[OAuth2Protocol::OAuth2Protocol_Prompt] = OAuth2Protocol::OAuth2Protocol_Prompt_None; $params['scope'] = sprintf('%s profile email', OAuth2Protocol::OpenIdConnect_Scope); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output2 = array(); parse_str($fragment, $output2); $this->assertTrue(!array_key_exists('access_token', $output2)); $this->assertTrue(empty($output2['access_token'])); $this->assertTrue(array_key_exists('id_token', $output2)); $this->assertTrue(!empty($output2['id_token'])); } public function testImplicitFlowAccessToken() { // use a public client $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token, 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get response $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('access_token', $output)); $this->assertTrue(!empty($output['access_token'])); $this->assertTrue(!array_key_exists('id_token', $output)); $this->assertTrue(empty($output['id_token'])); } public function testImplicitFlowResponseModePost() { // use a public client $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_IdToken . OAuth2Protocol::OAuth2Protocol_ResponseType_Delimiter . OAuth2Protocol::OAuth2Protocol_ResponseType_Token, 'scope' => sprintf('%s profile email %s', OAuth2Protocol::OpenIdConnect_Scope, OAuth2Protocol::OfflineAccess_Scope), OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_Consent, OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_ResponseMode => OAuth2Protocol::OAuth2Protocol_ResponseMode_FormPost, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); // do login $response = $this->call('POST', $url, array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $response = $this->action('POST', 'UserController@getConsent', array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get response $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(200); $this->assertEquals('application/x-www-form-urlencoded', $response->headers->get('Content-Type')); $content = $response->getContent(); $this->assertTrue(!empty($content)); $output = array(); parse_str($content, $output); $this->assertTrue(array_key_exists('access_token', $output)); $this->assertTrue(!empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); } public function testUserInfoEndpointGETAndBearerHeader() { $access_token = $this->testToken(); $response = $this->action("GET", "OAuth2UserApiController@userInfo", array(), array(), array(), array("HTTP_Authorization" => " Bearer " . $access_token)); $this->assertResponseStatus(200); $content = $response->getContent(); $this->assertTrue(!empty($content)); $user_info = json_decode($content, true); $this->assertTrue(isset($user_info['sub'])); } public function testUserInfoEndpointPOSTAndBearerHeader() { $access_token = $this->testToken(); $response = $this->action("POST", "OAuth2UserApiController@userInfo", array(), array(), array(), array("HTTP_Authorization" => " Bearer " . $access_token)); $this->assertResponseStatus(200); $content = $response->getContent(); $this->assertTrue(!empty($content)); $user_info = json_decode($content, true); $this->assertTrue(isset($user_info['sub'])); } public function testUserInfoEndpointPOSTAndBearerBody() { $access_token = $this->testToken(); $response = $this->action("POST", "OAuth2UserApiController@userInfo", array(), array ( 'access_token' => $access_token ), array(), array()); $this->assertResponseStatus(200); $content = $response->getContent(); $this->assertTrue(!empty($content)); $user_info = json_decode($content, true); $this->assertTrue(isset($user_info['sub'])); } public function testUserInfoEndpointPOSTAndBearerBodyRS512() { $access_token = $this->testToken ( 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ33.openstack.client', 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N585OtGKhg55', false ); $response = $this->action("POST", "OAuth2UserApiController@userInfo", array(), array ( 'access_token' => $access_token ), array(), array()); $this->assertResponseStatus(200); $user_info_response = $response->getContent(); $this->assertTrue($response->headers->get('content-type') === \utils\http\HttpContentType::JWT); $this->assertTrue(!empty($user_info_response)); $jwt = BasicJWTFactory::build($user_info_response); $this->assertTrue($jwt instanceof IJWS); } public function testHybridFlowCodeIdToken() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'id_token code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 1000, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $this->assertTrue(!array_key_exists('access_token', $output)); $this->assertTrue(empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); } public function testHybridFlowCodeIdTokenIdTokenHint() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'id_token code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 1000, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $this->assertTrue(!array_key_exists('access_token', $output)); $this->assertTrue(empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); $id_token = $output['id_token']; $jwt = BasicJWTFactory::build($id_token); $this->assertTrue($jwt instanceof IJWE); $recipient_key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_1, RSAJWKPEMPrivateKeySpecification::WithoutPassword, $jwt->getJOSEHeader()->getAlgorithm()->getString() ) ); $recipient_key->setKeyUse(JSONWebKeyPublicKeyUseValues::Encryption)->setId('recipient_public_key'); $jwt->setRecipientKey($recipient_key); $payload = $jwt->getPlainText(); $jwt = BasicJWTFactory::build($payload); $this->assertTrue($jwt instanceof IJWS); $jwk = OctetSequenceJWKFactory::build ( new OctetSequenceJWKSpecification ( $client_secret, JSONWebSignatureAndEncryptionAlgorithms::HS512 ) ); $jwk->setId('shared_secret'); $jwt->setKey($jwk); $verified = $jwt->verify(JSONWebSignatureAndEncryptionAlgorithms::HS512); $this->assertTrue($verified); // ok send as id token hint again .... $id_token_hint = $jwt->toCompactSerialization(); $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'id_token code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_None, OAuth2Protocol::OAuth2Protocol_IDTokenHint => $id_token_hint, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $this->assertTrue(!array_key_exists('access_token', $output)); $this->assertTrue(empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); // try with another key client private key signing (RSA) $claim_set = $jwt->getPayload()->getClaimSet(); $key = RSAJWKFactory::build ( new RSAJWKPEMPrivateKeySpecification ( TestSeeder::$client_private_key_2, RSAJWKPEMPrivateKeySpecification::WithoutPassword, JSONWebSignatureAndEncryptionAlgorithms::RS512 ) ); $key->setId('public_key_2'); $alg = new StringOrURI(JSONWebSignatureAndEncryptionAlgorithms::RS512); $jws = JWSFactory::build( new JWS_ParamsSpecification($key,$alg, $claim_set) ); // and sign with server private key $id_token_hint = $jws->toCompactSerialization(); $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'id_token code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_Prompt => OAuth2Protocol::OAuth2Protocol_Prompt_None, OAuth2Protocol::OAuth2Protocol_IDTokenHint => $id_token_hint, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('error', $output)); $this->assertTrue(!empty($output['error'])); $this->assertTrue($output['error'] == 'server_error'); $this->assertTrue(array_key_exists('error_description', $output)); $this->assertTrue(!empty($output['error_description'])); $this->assertTrue($output['error_description'] == 'original kid public_key_2 - current kid shared_secret'); } public function testHybridFlowCodeAccessToken() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code token', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 1000, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $this->assertTrue(array_key_exists('access_token', $output)); $this->assertTrue(!empty($output['access_token'])); $this->assertTrue(!array_key_exists('id_token', $output)); $this->assertTrue(empty($output['id_token'])); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $access_token = $response->access_token; $this->assertTrue(!empty($access_token)); $this->assertTrue($output['access_token'] !== $access_token); } public function testHybridFlowCodeAccessTokenIdToken() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code token id_token', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 1000, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $fragment = $comps['fragment']; $this->assertTrue(!empty($fragment)); $output = array(); parse_str($fragment, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $this->assertTrue(array_key_exists('access_token', $output)); $this->assertTrue(!empty($output['access_token'])); $this->assertTrue(array_key_exists('id_token', $output)); $this->assertTrue(!empty($output['id_token'])); $params = array ( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); } public function testTryingAuthCodeTwice() { $client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client'; $client_secret = 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg'; $params = array ( 'client_id' => $client_id, 'redirect_uri' => 'https://www.test.com/oauth2', 'response_type' => 'code', 'scope' => 'openid profile email', OAuth2Protocol::OAuth2Protocol_LoginHint => 'sebastian@tipit.net', OAuth2Protocol::OAuth2Protocol_MaxAge => 3200, OAuth2Protocol::OAuth2Protocol_Nonce => 'ctqg5FeNoYnZ', ); $response = $this->action("POST", "OAuth2ProviderController@authorize", $params, array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $response = $this->call('GET', $url); $this->assertResponseStatus(200); // verify that login hint (email) is populated $this->assertTrue(str_contains($response->getContent(), 'sebastian@tipit.net')); // do login $response = $this->action('POST', "UserController@postLogin", array ( 'username' => 'sebastian@tipit.net', 'password' => '1qaz2wsx', '_token' => Session::token() ) ); $this->assertResponseStatus(302); $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); //do consent $url = $response->getTargetUrl(); $response = $this->action('POST', "UserController@postConsent", array( 'trust' => 'AllowOnce', '_token' => Session::token() )); $this->assertResponseStatus(302); // get auth code $response = $this->action("GET", "OAuth2ProviderController@authorize", array(), array(), array(), array()); $this->assertResponseStatus(302); $url = $response->getTargetUrl(); $comps = @parse_url($url); $query = $comps['query']; $output = array(); parse_str($query, $output); $this->assertTrue(array_key_exists('code', $output)); $this->assertTrue(!empty($output['code'])); $params = array( 'code' => $output['code'], 'redirect_uri' => 'https://www.test.com/oauth2', 'grant_type' => OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode, ); // 1st $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); // 2nd $response = $this->action("POST", "OAuth2ProviderController@token", $params, array(), array(), // Symfony interally prefixes headers with "HTTP", so array("HTTP_Authorization" => " Basic " . base64_encode($client_id . ':' . $client_secret))); $this->assertResponseStatus(400); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $response = json_decode($content); $this->assertTrue($response->error === 'invalid_grant'); } public function testDiscovery() { $response = $this->action("GET", "OAuth2ProviderController@discovery"); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $this->assertTrue(!empty($content)); $response = json_decode($content, true); $this->assertTrue(isset($response['issuer'])); } public function testJWK() { $response = $this->action("GET", "OAuth2ProviderController@certs"); $this->assertResponseStatus(200); $this->assertEquals('application/json;charset=UTF-8', $response->headers->get('Content-Type')); $content = $response->getContent(); $this->assertTrue(!empty($content)); $response = json_decode($content, true); $this->assertTrue(isset($response['keys'])); } }