Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07d0b89

Browse files
author
Dave Rochwerger
committed
Merge branch 'draft-21'
Conflicts: lib/OAuth2.php
2 parents d55366d + 80f2d5a commit 07d0b89

File tree

6 files changed

+45
-35
lines changed

6 files changed

+45
-35
lines changed

lib/OAuth2.php

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
2-
require_once('OAuth2ServerException.php');
3-
require_once('OAuth2AuthenticateException.php');
4-
require_once('OAuth2RedirectException.php');
2+
require 'OAuth2ServerException.php';
3+
require 'OAuth2AuthenticateException.php';
4+
require 'OAuth2RedirectException.php';
55
/**
66
* @mainpage
77
* OAuth 2.0 server in PHP, originally written for
@@ -85,6 +85,7 @@ class OAuth2 {
8585
const CONFIG_TOKEN_TYPE = 'token_type'; // Token type to respond with. Currently only "Bearer" supported.
8686
const CONFIG_WWW_REALM = 'realm';
8787
const CONFIG_ENFORCE_INPUT_REDIRECT = 'enforce_redirect'; // Set to true to enforce redirect_uri on input for both authorize and token steps.
88+
const CONFIG_ENFORCE_STATE = 'enforce_state'; // Set to true to enforce state to be passed in authorization (see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.12)
8889

8990
/**
9091
* Regex to filter out the client identifier (described in Section 2 of IETF draft).
@@ -354,6 +355,7 @@ protected function setDefaultOptions() {
354355
self::CONFIG_WWW_REALM => self::DEFAULT_WWW_REALM,
355356
self::CONFIG_TOKEN_TYPE => self::TOKEN_TYPE_BEARER,
356357
self::CONFIG_ENFORCE_INPUT_REDIRECT => FALSE,
358+
self::CONFIG_ENFORCE_STATE => FALSE,
357359
self::CONFIG_SUPPORTED_SCOPES => array() // This is expected to be passed in on construction. Scopes can be an aribitrary string.
358360
);
359361
}
@@ -551,15 +553,13 @@ private function checkScope($required_scope, $available_scope) {
551553
* This would be called from the "/token" endpoint as defined in the spec.
552554
* Obviously, you can call your endpoint whatever you want.
553555
*
554-
* FIXME: According to section 4.1.3 (http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.3),
555-
* if the "Authorization Request" (auth_code) contained the redirect_uri, then it becomes mandatory when requesting the access token.
556-
* This is *not* currently enforced in this library.
557-
*
558556
* @param $inputData - The draft specifies that the parameters should be
559557
* retrieved from POST, but you can override to whatever method you like.
560558
* @throws OAuth2ServerException
561559
*
562560
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4
561+
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.6
562+
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-4.1.3
563563
*
564564
* @ingroup oauth2_section_4
565565
*/
@@ -617,10 +617,13 @@ public function grantAccessToken(array $inputData = NULL, array $authHeaders = N
617617
if ($stored === NULL || $client[0] != $stored["client_id"])
618618
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_GRANT, "Refresh token doesn't exist or is invalid for the client");
619619

620-
// Validate the redirect URI
620+
// Validate the redirect URI. They must match EXACTLY (as opposed to authorization step where they only need to have the same beginning).
621+
// See http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.6
622+
// Because we store the validated redirect_uri in getAuthorizeParams() (which is either the stored or input param) we are able to
623+
// do this check everytime (regardless of whether a confidential or public client is being used).
621624
$missing = (!$stored["redirect_uri"] && !$input["redirect_uri"]); // both stored and supplied are missing - we must have at least one!
622-
if ($missing || !$this->validateRedirectUri($input["redirect_uri"], $stored["redirect_uri"]))
623-
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, "The redirect URI is missing or invalid");
625+
if ($missing || $input["redirect_uri"] !== $stored["redirect_uri"])
626+
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, "The redirect URI is missing or do not match");
624627

625628
if ($stored["expires"] < time())
626629
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_GRANT, "The authorization code has expired");
@@ -702,7 +705,7 @@ public function grantAccessToken(array $inputData = NULL, array $authHeaders = N
702705

703706
// Check scope, if provided
704707
if ($input["scope"] && (!is_array($stored) || !isset($stored["scope"]) || !$this->checkScope($input["scope"], $stored["scope"])))
705-
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_SCOPE);
708+
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_SCOPE, 'An unsupported scope was requested.');
706709

707710
$user_id = isset($stored['user_id']) ? $stored['user_id'] : null;
708711
$token = $this->createAccessToken($client[0], $user_id, $stored['scope']);
@@ -739,7 +742,7 @@ protected function getClientCredentials(array $inputData, array $authHeaders) {
739742
return array($authHeaders['PHP_AUTH_USER'], $authHeaders['PHP_AUTH_PW']);
740743
}
741744
elseif (empty($inputData['client_id'])) { // No credentials were specified
742-
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT);
745+
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, 'Client id was not found in the headers or body');
743746
}
744747
else {
745748
// This method is not recommended, but is supported by specification
@@ -751,8 +754,10 @@ protected function getClientCredentials(array $inputData, array $authHeaders) {
751754

752755
/**
753756
* Pull the authorization request data out of the HTTP request.
754-
* The redirect_uri is OPTIONAL as per draft 20. But your implenetation can enforce it
755-
* by setting CONFIG_ENFORCE_INPUT_REDIRECT to true.
757+
* - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it
758+
* by setting CONFIG_ENFORCE_INPUT_REDIRECT to true.
759+
* - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that
760+
* CSRF protection is MANDATORY. You can enforce this by setting the CONFIG_ENFORCE_STATE to true.
756761
*
757762
* @param $inputData - The draft specifies that the parameters should be
758763
* retrieved from GET, but you can override to whatever method you like.
@@ -762,6 +767,7 @@ protected function getClientCredentials(array $inputData, array $authHeaders) {
762767
*
763768
* @throws OAuth2ServerException
764769
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.1
770+
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.12
765771
*
766772
* @ingroup oauth2_section_3
767773
*/
@@ -786,8 +792,8 @@ public function getAuthorizeParams(array $inputData = NULL) {
786792

787793
// Get client details
788794
$stored = $this->storage->getClientDetails($input["client_id"]);
789-
if (empty($stored) || !is_array($stored)) {
790-
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT);
795+
if ($stored === FALSE) {
796+
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, "Client id does not exist");
791797
}
792798

793799
// Make sure a valid redirect_uri was supplied. If specified, it must match the stored URI.
@@ -801,7 +807,7 @@ public function getAuthorizeParams(array $inputData = NULL) {
801807
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'The redirect URI is mandatory and was not supplied.');
802808
}
803809
if ($stored["redirect_uri"] && $input["redirect_uri"] && !$this->validateRedirectUri($input["redirect_uri"], $stored["redirect_uri"])) {
804-
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'The rediect URI provided is missing or does not match');
810+
throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'The redirect URI provided is missing or does not match');
805811
}
806812

807813
// Select the redirect URI
@@ -819,7 +825,11 @@ public function getAuthorizeParams(array $inputData = NULL) {
819825

820826
// Validate that the requested scope is supported
821827
if ($input["scope"] && !$this->checkScope($input["scope"], $this->getVariable(self::CONFIG_SUPPORTED_SCOPES)))
822-
throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_SCOPE, NULL, $input["state"]);
828+
throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_SCOPE, 'An unsupported scope was requested.', $input["state"]);
829+
830+
// Validate state parameter exists (if configured to enforce this)
831+
if ($this->getVariable(self::CONFIG_ENFORCE_STATE) && !$input["state"])
832+
throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_REQUEST, "The state parameter is required.");
823833

824834
// Return retrieved client details together with input
825835
return ($input + $stored);
@@ -1047,8 +1057,8 @@ protected function genAuthCode() {
10471057
*/
10481058
protected function getAuthorizationHeader() {
10491059
return array(
1050-
'PHP_AUTH_USER' => $_SERVER['PHP_AUTH_USER'],
1051-
'PHP_AUTH_PW' => $_SERVER['PHP_AUTH_PW']
1060+
'PHP_AUTH_USER' => isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '',
1061+
'PHP_AUTH_PW' => isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '',
10521062
);
10531063
}
10541064

server/examples/mongo/lib/OAuth2StorageMongo.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
*
77
*/
88

9-
require_once __DIR__.'/../../../../lib/OAuth2.php';
10-
require_once __DIR__.'/../../../../lib/IOAuth2Storage.php';
11-
require_once __DIR__.'/../../../../lib/IOAuth2GrantCode.php';
12-
require_once __DIR__.'/../../../../lib/IOAuth2RefreshTokens.php';
9+
require __DIR__.'/../../../../lib/OAuth2.php';
10+
require __DIR__.'/../../../../lib/IOAuth2Storage.php';
11+
require __DIR__.'/../../../../lib/IOAuth2GrantCode.php';
12+
require __DIR__.'/../../../../lib/IOAuth2RefreshTokens.php';
1313

1414
/**
1515
* Mongo storage engine for the OAuth2 Library.

server/examples/pdo/lib/OAuth2StoragePdo.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
* new PDOOAuth2( new PDO('mysql:dbname=mydb;host=localhost', 'user', 'pass') );
99
*/
1010

11-
require_once __DIR__.'/../../../../lib/OAuth2.php';
12-
require_once __DIR__.'/../../../../lib/IOAuth2Storage.php';
13-
require_once __DIR__.'/../../../../lib/IOAuth2GrantCode.php';
14-
require_once __DIR__.'/../../../../lib/IOAuth2RefreshTokens.php';
11+
require __DIR__.'/../../../../lib/OAuth2.php';
12+
require __DIR__.'/../../../../lib/IOAuth2Storage.php';
13+
require __DIR__.'/../../../../lib/IOAuth2GrantCode.php';
14+
require __DIR__.'/../../../../lib/IOAuth2RefreshTokens.php';
1515

1616
/**
1717
* PDO storage engine for the OAuth2 Library.

tests/All_OAuth2_Tests.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public function __construct() {
1313
$this->setName ( 'OAuth2Suite' );
1414

1515
foreach (glob(__DIR__.'/*Test.php') as $filename) {
16-
require_once($filename);
16+
require $filename;
1717
$class = basename($filename, '.php');
1818
$this->addTestSuite($class);
1919
}

tests/OAuth2OutputTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
2-
require_once(__DIR__ . '/../lib/OAuth2.php');
3-
require_once(__DIR__ . '/../lib/IOAuth2Storage.php');
4-
require_once(__DIR__ . '/../lib/IOAuth2GrantCode.php');
2+
require __DIR__ . '/../lib/OAuth2.php';
3+
require __DIR__ . '/../lib/IOAuth2Storage.php';
4+
require __DIR__ . '/../lib/IOAuth2GrantCode.php';
55

66
/**
77
* OAuth2 test cases that invovle capturing output.

tests/OAuth2Test.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
2-
require_once(__DIR__ . '/../lib/OAuth2.php');
3-
require_once(__DIR__ . '/../lib/IOAuth2Storage.php');
4-
require_once(__DIR__ . '/../lib/IOAuth2GrantCode.php');
2+
require __DIR__ . '/../lib/OAuth2.php';
3+
require __DIR__ . '/../lib/IOAuth2Storage.php';
4+
require __DIR__ . '/../lib/IOAuth2GrantCode.php';
55

66
/**
77
* OAuth2 test case.

0 commit comments

Comments
 (0)