/** * Check that a valid access token has been provided. * The token is returned (as an associative array) if valid. * * The scope parameter defines any required scope that the token must have. * If a scope param is provided and the token does not have the required * scope, we bounce the request. * * Some implementations may choose to return a subset of the protected * resource (i.e. "public" data) if the user has not provided an access * token or if the access token is invalid or expired. * * The IETF spec says that we should send a 401 Unauthorized header and * bail immediately so that's what the defaults are set to. You can catch * the exception thrown and behave differently if you like (log errors, allow * public access for missing tokens, etc) * * @param string $tokenParam * @param string $scope A space-separated string of required scope(s), if you want to check for scope. * * @throws OAuth2AuthenticateException * @return IOAuth2AccessToken Token * * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-7 * * @ingroup oauth2_section_7 */ public function verifyAccessToken($tokenParam, $scope = null) { $tokenType = $this->getVariable(self::CONFIG_TOKEN_TYPE); $realm = $this->getVariable(self::CONFIG_WWW_REALM); if (!$tokenParam) { // Access token was not provided throw new OAuth2AuthenticateException(self::HTTP_BAD_REQUEST, $tokenType, $realm, self::ERROR_INVALID_REQUEST, 'The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.', $scope); } // Get the stored token data (from the implementing subclass) $token = $this->storage->getAccessToken($tokenParam); if (!$token) { throw new OAuth2AuthenticateException(self::HTTP_UNAUTHORIZED, $tokenType, $realm, self::ERROR_INVALID_GRANT, 'The access token provided is invalid.', $scope, 460); } // Check token expiration (expires is a mandatory paramter) if ($token->hasExpired()) { throw new OAuth2AuthenticateException(self::HTTP_UNAUTHORIZED, $tokenType, $realm, self::ERROR_INVALID_GRANT, 'The access token provided has expired.', $scope, 461); } // Check scope, if provided // If token doesn't have a scope, it's null/empty, or it's insufficient, then throw an error if ($scope && (!$token->getScope() || !$this->checkScope($scope, $token->getScope()))) { throw new OAuth2AuthenticateException(self::HTTP_FORBIDDEN, $tokenType, $realm, self::ERROR_INSUFFICIENT_SCOPE, 'The request requires higher privileges than provided by the access token.', $scope); } return $token; }