Skip to content

Commit

Permalink
Fix for token id_token combination as per http://openid.net/specs/oau…
Browse files Browse the repository at this point in the history
…th-v2-multiple-response-types-1_0.html#Combinations

matching the sample authorization request from the same source and section

rename TokenIdToken to IdTokenToken
  • Loading branch information
npmarrin authored and bshaffer committed Oct 7, 2014
1 parent ee912be commit ca88353
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 26 deletions.
5 changes: 3 additions & 2 deletions src/OAuth2/OpenID/Controller/AuthorizeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public function validateAuthorizeRequest(RequestInterface $request, ResponseInte

$nonce = $request->query('nonce');

// Validate required nonce for "id_token" and "token id_token"
if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_TOKEN_ID_TOKEN))) {
// Validate required nonce for "id_token", "token id_token" and "id_token token"
if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_TOKEN_ID_TOKEN, self::RESPONSE_TYPE_ID_TOKEN_TOKEN))) {
$response->setError(400, 'invalid_nonce', 'This application requires you specify a nonce parameter');

return false;
Expand All @@ -76,6 +76,7 @@ protected function getValidResponseTypes()
self::RESPONSE_TYPE_AUTHORIZATION_CODE,
self::RESPONSE_TYPE_ID_TOKEN,
self::RESPONSE_TYPE_TOKEN_ID_TOKEN,
self::RESPONSE_TYPE_ID_TOKEN_TOKEN,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ interface AuthorizeControllerInterface
{
const RESPONSE_TYPE_ID_TOKEN = 'id_token';
const RESPONSE_TYPE_TOKEN_ID_TOKEN = 'token id_token';
const RESPONSE_TYPE_ID_TOKEN_TOKEN = 'id_token token';
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use OAuth2\ResponseType\AccessTokenInterface;

class TokenIdToken implements TokenIdTokenInterface
class IdTokenToken implements IdTokenTokenInterface
{
protected $accessToken;
protected $idToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

use OAuth2\ResponseType\ResponseTypeInterface;

interface TokenIdTokenInterface extends ResponseTypeInterface
interface IdTokenTokenInterface extends ResponseTypeInterface
{
}
23 changes: 13 additions & 10 deletions src/OAuth2/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use OAuth2\ResponseType\AccessToken;
use OAuth2\ResponseType\JwtAccessToken;
use OAuth2\OpenID\ResponseType\IdToken;
use OAuth2\OpenID\ResponseType\TokenIdToken;
use OAuth2\OpenID\ResponseType\IdTokenToken;
use OAuth2\TokenType\TokenTypeInterface;
use OAuth2\TokenType\Bearer;
use OAuth2\GrantType\GrantTypeInterface;
Expand Down Expand Up @@ -79,7 +79,8 @@ class Server implements ResourceControllerInterface,
'token' => 'OAuth2\ResponseType\AccessTokenInterface',
'code' => 'OAuth2\ResponseType\AuthorizationCodeInterface',
'id_token' => 'OAuth2\OpenID\ResponseType\IdTokenInterface',
'token id_token' => 'OAuth2\OpenID\ResponseType\TokenIdTokenInterface',
'token id_token' => 'OAuth2\OpenID\ResponseType\IdTokenTokenInterface',
'id_token token' => 'OAuth2\OpenID\ResponseType\IdTokenTokenInterface',
);

/**
Expand Down Expand Up @@ -451,7 +452,8 @@ protected function createDefaultAuthorizeController()
if ($this->config['use_openid_connect'] && !isset($this->responseTypes['id_token'])) {
$this->responseTypes['id_token'] = $this->createDefaultIdTokenResponseType();
if ($this->config['allow_implicit']) {
$this->responseTypes['token id_token'] = $this->createDefaultTokenIdTokenResponseType();
$this->responseTypes['token id_token'] = $this->createDefaultIdTokenTokenResponseType();
$this->responseTypes['id_token token'] = $this->createDefaultIdTokenTokenResponseType();
}
}

Expand Down Expand Up @@ -555,7 +557,8 @@ protected function getDefaultResponseTypes()
if ($this->config['use_openid_connect']) {
$responseTypes['id_token'] = $this->getIdTokenResponseType();
if ($this->config['allow_implicit']) {
$responseTypes['token id_token'] = $this->getTokenIdTokenResponseType();
$responseTypes['token id_token'] = $this->getIdTokenTokenResponseType();
$responseTypes['id_token token'] = $this->getIdTokenTokenResponseType();
}
}

Expand Down Expand Up @@ -636,13 +639,13 @@ protected function getIdTokenResponseType()
return $this->createDefaultIdTokenResponseType();
}

protected function getTokenIdTokenResponseType()
protected function getIdTokenTokenResponseType()
{
if (isset($this->responseTypes['token id_token'])) {
return $this->responseTypes['token id_token'];
if (isset($this->responseTypes['id_token token'])) {
return $this->responseTypes['id_token token'];
}

return $this->createDefaultTokenIdTokenResponseType();
return $this->createDefaultIdTokenTokenResponseType();
}

/**
Expand Down Expand Up @@ -716,9 +719,9 @@ protected function createDefaultIdTokenResponseType()
return new IdToken($this->storages['user_claims'], $this->storages['public_key'], $config);
}

protected function createDefaultTokenIdTokenResponseType()
protected function createDefaultIdTokenTokenResponseType()
{
return new TokenIdToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
return new IdTokenToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
}

public function getResponse()
Expand Down
25 changes: 18 additions & 7 deletions test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use OAuth2\OpenID\Controller\AuthorizeController;
use OAuth2\OpenID\ResponseType\IdToken;
use OAuth2\OpenID\ResponseType\TokenIdToken;
use OAuth2\OpenID\ResponseType\IdTokenToken;
use OAuth2\ResponseType\AccessToken;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
Expand Down Expand Up @@ -43,6 +43,14 @@ public function testValidateAuthorizeRequest()

// Test valid token id_token request
$request->query['response_type'] = 'token id_token';
$this->validateAuthorizeRequest($server, $request, $response);

// Test valid id_token token request
$request->query['response_type'] = 'id_token token';
$this->validateAuthorizeRequest($server, $request, $response);
}

private function validateAuthorizeRequest($server, $request, $response){
$server->handleAuthorizeRequest($request, $response, true);

$parts = parse_url($response->getHttpHeader('Location'));
Expand Down Expand Up @@ -72,15 +80,18 @@ public function testMissingNonce()
));

// Test missing nonce for 'id_token' response type
$server->handleAuthorizeRequest($request, $response, true);
$this->missingNonce($server, $request, $response);

$params = $response->getParameters();
// Test missing nonce for 'token id_token' response type
$request->query['response_type'] = 'token id_token';
$this->missingNonce($server, $request, $response);

$this->assertEquals($params['error'], 'invalid_nonce');
$this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
// Test missing nonce for 'id_token token' response type
$request->query['response_type'] = 'id_token token';
$this->missingNonce($server, $request, $response);
}

// Test missing nonce for 'id_token' response type
$request->query['response_type'] = 'token id_token';
private function missingNonce($server, $request, $response){
$server->handleAuthorizeRequest($request, $response, true);

$params = $response->getParameters();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use OAuth2\GrantType\ClientCredentials;
use OAuth2\ResponseType\AccessToken;

class TokenIdTokenTest extends \PHPUnit_Framework_TestCase
class IdTokenTokenTest extends \PHPUnit_Framework_TestCase
{

public function testHandleAuthorizeRequest()
Expand All @@ -25,6 +25,21 @@ public function testHandleAuthorizeRequest()
'nonce' => 'test',
));

$this->handleAuthorizeRequest($server, $request);

$request = new Request(array(
'response_type' => 'id_token token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid',
'state' => 'test',
'nonce' => 'test',
));

$this->handleAuthorizeRequest($server, $request);
}

private function handleAuthorizeRequest($server, $request){
$server->handleAuthorizeRequest($request, $response = new Response(), true);

$this->assertEquals($response->getStatusCode(), 302);
Expand Down Expand Up @@ -83,7 +98,8 @@ private function getTestServer($config = array())
'token' => new AccessToken($memoryStorage, $memoryStorage),
'id_token' => new IdToken($memoryStorage, $memoryStorage, $config),
);
$responseTypes['token id_token'] = new TokenIdToken($responseTypes['token'], $responseTypes['id_token']);
$responseTypes['token id_token'] = new IdTokenToken($responseTypes['token'], $responseTypes['id_token']);
$responseTypes['id_token token'] = new IdTokenToken($responseTypes['token'], $responseTypes['id_token']);

$server = new Server($memoryStorage, $config, array(), $responseTypes);
$server->addGrantType(new ClientCredentials($memoryStorage));
Expand Down
10 changes: 7 additions & 3 deletions test/OAuth2/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()

$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertNull($server->getResponseType('token id_token'));
$this->assertNull($server->getResponseType('id_token token'));
}

/**
Expand Down Expand Up @@ -561,7 +562,8 @@ public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOk
$server->getAuthorizeController();

$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\TokenIdTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}

public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
Expand All @@ -579,7 +581,8 @@ public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOk
$server->getAuthorizeController();

$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\TokenIdTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}

public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
Expand All @@ -600,7 +603,8 @@ public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTyp
$server->getAuthorizeController();

$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\TokenIdTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('token id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}

/**
Expand Down

0 comments on commit ca88353

Please sign in to comment.