/** * Pull the authorization request data out of the HTTP request. * - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it * by setting CONFIG_ENFORCE_INPUT_REDIRECT to true. * - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that * CSRF protection is MANDATORY. You can enforce this by setting the CONFIG_ENFORCE_STATE to true. * * @param $inputData - The draft specifies that the parameters should be * retrieved from GET, but you can override to whatever method you like. * @return * The authorization parameters so the authorization server can prompt * the user for approval if valid. * * @throws OAuth2ServerException * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.1 * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.12 * * @ingroup oauth2_section_3 */ public function getAuthorizeParams(array $inputData = NULL) { $filters = array("client_id" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => self::CLIENT_ID_REGEXP), "flags" => FILTER_REQUIRE_SCALAR), "response_type" => array("flags" => FILTER_REQUIRE_SCALAR), "redirect_uri" => array("filter" => FILTER_SANITIZE_URL), "state" => array("flags" => FILTER_REQUIRE_SCALAR), "scope" => array("flags" => FILTER_REQUIRE_SCALAR)); if (!isset($inputData)) { $inputData = $_GET; } $input = filter_var_array($inputData, $filters); // Make sure a valid client id was supplied (we can not redirect because we were unable to verify the URI) if (!$input["client_id"]) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, "No client id supplied"); // We don't have a good URI to use } // Get client details $stored = $this->storage->getClientDetails($input["client_id"]); if ($stored === FALSE) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, "Client id does not exist"); } // Make sure a valid redirect_uri was supplied. If specified, it must match the stored URI. // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-3.1.2 // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.2.1 // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.2.2.1 if (!$input["redirect_uri"] && !$stored["redirect_uri"]) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'No redirect URL was supplied or stored.'); } if ($this->getVariable(self::CONFIG_ENFORCE_INPUT_REDIRECT) && !$input["redirect_uri"]) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'The redirect URI is mandatory and was not supplied.'); } // Only need to validate if redirect_uri provided on input and stored. if ($stored["redirect_uri"] && $input["redirect_uri"] && !$this->validateRedirectUri($input["redirect_uri"], $stored["redirect_uri"])) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, 'The redirect URI provided is missing or does not match'); } // Select the redirect URI $input["redirect_uri"] = isset($input["redirect_uri"]) ? $input["redirect_uri"] : $stored["redirect_uri"]; // type and client_id are required if (!$input["response_type"]) { throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_REQUEST, 'Invalid or missing response type.', $input["state"]); } // Check requested auth response type against interfaces of storage engine $reflect = new ReflectionClass($this->storage); if (!$reflect->hasConstant('RESPONSE_TYPE_' . strtoupper($input['response_type']))) { throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_UNSUPPORTED_RESPONSE_TYPE, NULL, $input["state"]); } // Validate that the requested scope is supported if ($input["scope"] && !$this->checkScope($input["scope"], $this->getVariable(self::CONFIG_SUPPORTED_SCOPES))) { throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_SCOPE, 'An unsupported scope was requested.', $input["state"]); } // Validate state parameter exists (if configured to enforce this) if ($this->getVariable(self::CONFIG_ENFORCE_STATE) && !$input["state"]) { throw new OAuth2RedirectException($input["redirect_uri"], self::ERROR_INVALID_REQUEST, "The state parameter is required."); } // Return retrieved client details together with input return $input + $stored; }
/** * Pull the authorization request data out of the HTTP request. * - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it * by setting CONFIG_ENFORCE_INPUT_REDIRECT to true. * - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that * CSRF protection is MANDATORY. You can enforce this by setting the CONFIG_ENFORCE_STATE to true. * * @param $inputData - The draft specifies that the parameters should be * retrieved from GET, but you can override to whatever method you like. * @return * The authorization parameters so the authorization server can prompt * the user for approval if valid. * * @throws OAuth2ServerException * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.1 * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.12 * * @ingroup oauth2_section_3 */ public function getAuthorizeParams($inputData) { if (!isset($inputData)) { $inputData = $_GET; } $input = $inputData; // THROW ERROR IF client_id IS MISSING if (!$input["client_id"]) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'Client id required')); echo $error; exit; } // GET CLIENT DETAILS $stored = $this->storage->getClientDetails($input["client_id"]); if ($stored === FALSE) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'Client not found or not provided')); echo $error; exit; } // Make sure a valid redirect_uri was supplied. If specified, it must match the stored URI. // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-3.1.2 // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.1.2.1 // @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.2.2.1 if (!$input["redirect_uri"] && !$stored["redirect_uri"]) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'redirect_uri is require')); echo $error; exit; } if ($this->getVariable(self::CONFIG_ENFORCE_INPUT_REDIRECT) && !$input["redirect_uri"]) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'redirect_uri is require by Mydwellworks OAuth API')); echo $error; exit; } // Only need to validate if redirect_uri provided on input and stored. if ($stored["redirect_uri"] && $input["redirect_uri"] && !$this->validateRedirectUri($input["redirect_uri"], $stored["redirect_uri"])) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'The redirect_uri is missing or does not match allowed uri')); echo $error; exit; } // Select the redirect URI $input["redirect_uri"] = isset($input["redirect_uri"]) ? $input["redirect_uri"] : $stored["redirect_uri"]; // type and client_id are required if (!$input["response_type"]) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'Invalid or missing response_type')); echo $error; exit; } if ($input['response_type'] != self::RESPONSE_TYPE_AUTH_CODE && $input['response_type'] != self::RESPONSE_TYPE_ACCESS_TOKEN) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'response_type invalid')); echo $error; exit; } // Validate that the requested scope is supported if ($input["scope"] && !$this->checkScope($input["scope"], $this->getVariable(self::CONFIG_SUPPORTED_SCOPES))) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'Unsuportted scope')); echo $error; exit; } // Validate state parameter exists (if configured to enforce this) if ($this->getVariable(self::CONFIG_ENFORCE_STATE) && !$input["state"]) { header("Content-Type: application/json"); header("Cache-Control: no-store"); $error = json_encode(array('Error' => 'state is required by Mydwellworks')); echo $error; exit; } // Return retrieved client details together with input return $input + $stored; }