Example #1
0
 /**
  * Grant or deny a requested access token.
  *
  * This would be called from the "/token" endpoint as defined in the spec.
  * Obviously, you can call your endpoint whatever you want.
  * Draft specifies that the authorization parameters should be retrieved from POST, but you can override to whatever method you like.
  *
  * @param  Request $request (optional) The request
  *
  * @return Response
  * @throws OAuth2ServerException
  *
  * @see      http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4
  * @see      http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-10.6
  * @see      http://tools.ietf.org/html/draft-ietf-oauth-v2-21#section-4.1.3
  *
  * @ingroup  oauth2_section_4
  */
 public function grantAccessToken(Request $request = null)
 {
     $filters = array("grant_type" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => self::GRANT_TYPE_REGEXP), "flags" => FILTER_REQUIRE_SCALAR), "scope" => array("flags" => FILTER_REQUIRE_SCALAR), "code" => array("flags" => FILTER_REQUIRE_SCALAR), "redirect_uri" => array("filter" => FILTER_SANITIZE_URL), "username" => array("flags" => FILTER_REQUIRE_SCALAR), "password" => array("flags" => FILTER_REQUIRE_SCALAR), "refresh_token" => array("flags" => FILTER_REQUIRE_SCALAR));
     if ($request === null) {
         $request = Request::createFromGlobals();
     }
     // Input data by default can be either POST or GET
     if ($request->getMethod() === 'POST') {
         $inputData = $request->request->all();
     } else {
         $inputData = $request->query->all();
     }
     // Basic authorization header
     $authHeaders = $this->getAuthorizationHeader($request);
     // Filter input data
     $input = filter_var_array($inputData, $filters);
     // Grant Type must be specified.
     if (!$input["grant_type"]) {
         throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_REQUEST, 'Invalid grant_type parameter or parameter missing');
     }
     // Authorize the client
     $clientCredentials = $this->getClientCredentials($inputData, $authHeaders);
     $client = $this->storage->getClient($clientCredentials[0]);
     if (!$client) {
         throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, 'The client credentials are invalid');
     }
     if ($this->storage->checkClientCredentials($client, $clientCredentials[1]) === false) {
         throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_CLIENT, 'The client credentials are invalid');
     }
     if (!$this->storage->checkRestrictedGrantType($client, $input["grant_type"])) {
         throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_UNAUTHORIZED_CLIENT, 'The grant type is unauthorized for this client_id');
     }
     // Do the granting
     switch ($input["grant_type"]) {
         case self::GRANT_TYPE_AUTH_CODE:
             // returns array('data' => data, 'scope' => scope)
             $stored = $this->grantAccessTokenAuthCode($client, $input);
             break;
         case self::GRANT_TYPE_USER_CREDENTIALS:
             // returns: true || array('scope' => scope)
             $stored = $this->grantAccessTokenUserCredentials($client, $input);
             break;
         case self::GRANT_TYPE_CLIENT_CREDENTIALS:
             // returns: true || array('scope' => scope)
             $stored = $this->grantAccessTokenClientCredentials($client, $input, $clientCredentials);
             break;
         case self::GRANT_TYPE_REFRESH_TOKEN:
             // returns array('data' => data, 'scope' => scope)
             $stored = $this->grantAccessTokenRefreshToken($client, $input);
             break;
         default:
             if (filter_var($input["grant_type"], FILTER_VALIDATE_URL)) {
                 // returns: true || array('scope' => scope)
                 $stored = $this->grantAccessTokenExtension($client, $inputData, $authHeaders);
             } else {
                 throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_REQUEST, 'Invalid grant_type parameter or parameter missing');
             }
     }
     if (!is_array($stored)) {
         $stored = array();
     }
     // if no scope provided to check against $input['scope'] then application defaults are set
     // if no data is provided than null is set
     $stored += array('scope' => $this->getVariable(self::CONFIG_SUPPORTED_SCOPES, null), 'data' => null, 'access_token_lifetime' => $this->getVariable(self::CONFIG_ACCESS_LIFETIME), 'issue_refresh_token' => true, 'refresh_token_lifetime' => $this->getVariable(self::CONFIG_REFRESH_LIFETIME));
     $scope = $stored['scope'];
     if ($input["scope"]) {
         // Check scope, if provided
         if (!isset($stored["scope"]) || !$this->checkScope($input["scope"], $stored["scope"])) {
             throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_SCOPE, 'An unsupported scope was requested.');
         }
         $scope = $input["scope"];
     }
     $token = $this->createAccessToken($client, $stored['data'], $scope, $stored['access_token_lifetime'], $stored['issue_refresh_token'], $stored['refresh_token_lifetime']);
     return new Response(json_encode($token), 200, $this->getJsonHeaders());
 }