Пример #1
0
 /**
  * Processes an OAuth refresh token request.
  *
  * @param Request $request the OAuth token request
  * @param Response $response the response
  */
 protected function tokenFromRefreshToken($request, $response)
 {
     $store = StoreManager::instance();
     $client = $this->oauth->getClient();
     if (!isset($request['refresh_token']) || $request['refresh_token'] == '') {
         $this->logger->log(LogLevel::ERROR, 'Token request failed: refresh_token not set');
         $response->setError('invalid_request', 'refresh_token not set');
         return;
     }
     $refresh_token = RefreshToken::decode($request['refresh_token']);
     if (!$refresh_token->isValid()) {
         $this->logger->log(LogLevel::ERROR, 'Token request failed: Refresh token not valid');
         $response->setError('invalid_grant', 'Refresh token not valid');
         return;
     }
     $authorization = $refresh_token->getAuthorization();
     if ($authorization->getClient()->getStoreID() != $client->getStoreID()) {
         $this->logger->log(LogLevel::ERROR, 'Token request failed: this client (' . $client->getStoreID() . ') does not match the client stored in refresh token (' . $authorization->getClient()->getStoreID() . ')');
         $response->setError('invalid_grant', 'this client does not match the client stored in refresh token');
         $response->renderJSON();
         return;
     }
     $authorization->revokeTokensFromSource($refresh_token);
     $scope = $refresh_token->getScope();
     // If we issue, we delete the old refresh token so that it can't be used again
     $refresh_token->revoke();
     $authorization->resetAuthState();
     $store->saveAuth($authorization);
     $response->loadData($authorization->issueTokens($scope, SIMPLEID_SHORT_TOKEN_EXPIRES_IN, $refresh_token));
     // Call modules
     $this->mgr->invokeAll('oAuthToken', 'refresh_token', $authorization, $request, $response, $scope);
     return $authorization;
 }
 /**
  * Registration endpoint
  */
 public function register()
 {
     $rand = new Random();
     $response = new Response();
     $this->checkHttps('error');
     $this->logger->log(LogLevel::DEBUG, 'SimpleID\\Protocols\\Connect\\ConnectClientRegistrationModule->register');
     // Access token OR rate limit
     if (!$this->isTokenAuthorized(self::CLIENT_REGISTRATION_INIT_SCOPE)) {
         $limiter = new RateLimiter('connect_register');
         if (!$limiter->throttle()) {
             header('Retry-After: ' . $limiter->getInterval());
             // We never display a log for rate limit errors
             $response->setError('invalid_request', 'client has been blocked from making further requests')->renderJSON(429);
             return;
         }
     }
     if (!$this->f3->exists('BODY')) {
         $response->setError('invalid_request')->renderJSON();
         return;
     }
     $request = json_decode($this->f3->get('BODY'), true);
     if ($request == null) {
         $response->setError('invalid_request', 'unable to parse body')->renderJSON();
         return;
     }
     if (!isset($request['redirect_uris'])) {
         $response->setError('invalid_redirect_uri', 'redirect_uris missing')->renderJSON();
         return;
     }
     // Verify redirect_uri based on application_type
     $application_type = isset($request['application_type']) ? $request['application_type'] : 'web';
     $grant_types = isset($request['grant_types']) ? $request['grant_types'] : array('authorization_code');
     foreach ($request['redirect_uris'] as $redirect_uri) {
         $parts = parse_url($redirect_uri);
         if (isset($parts['fragment'])) {
             $response->setError('invalid_redirect_uri', 'redirect_uris cannot contain a fragment')->renderJSON();
             return;
         }
         if ($application_type == 'web' && in_array('implicit', $grant_types)) {
             if (strtolower($parts['scheme']) != 'https' || strtolower($parts['host']) == 'localhost' && $parts['host'] == '127.0.0.1') {
                 $response->setError('invalid_redirect_uri', 'implicit grant type must use https URIs')->renderJSON();
                 return;
             }
         } elseif ($application_type == 'native') {
             // Native Clients MUST only register redirect_uris using custom URI schemes or URLs using the http: scheme with localhost as the hostname.
             // Authorization Servers MAY place additional constraints on Native Clients.
             // Authorization Servers MAY reject Redirection URI values using the http scheme, other than the localhost case for Native Clients.
             // The Authorization Server MUST verify that all the registered redirect_uris conform to these constraints. This prevents sharing a Client ID across different types of Clients.
             if (strtolower($parts['scheme']) == 'http' && (strtolower($parts['host']) != 'localhost' || $parts['host'] != '127.0.0.1') || strtolower($parts['scheme']) == 'https') {
                 $response->setError('invalid_redirect_uri', 'native clients cannot use https URIs')->renderJSON();
                 return;
             }
         }
     }
     // Verify sector_identifier_url
     $subject_type = isset($request['subject_type']) ? $request['subject_type'] : 'public';
     if (isset($request['sector_identifier_uri'])) {
         if (!$this->verifySectorIdentifier($request['sector_identifier_uri'], $request['redirect_uris'])) {
             $response->setError('invalid_client_metadata', 'cannot verify sector_identifier_uri')->renderJSON();
             return;
         }
     }
     $client = new ConnectDynamicClient();
     $client_id = $client->getStoreID();
     // Map data
     foreach ($request as $name => $value) {
         $parts = explode('#', $name, 2);
         $client_path = isset(self::$metadata_map[$parts[0]]) ? self::$metadata_map[$parts[0]] : 'connect.' . $parts[0];
         if (isset($parts[1])) {
             $client_path .= '#' . $locale;
         }
         $client->pathSet($client_path, $value);
     }
     $client->fetchJWKs();
     $response->loadData($request);
     $response->loadData(array('client_id' => $client->getStoreID(), 'registration_client_uri' => $this->getCanonicalURL('connect/client/' . $client->getStoreID()), 'client_id_issued_at' => time()));
     if ($client['oauth']['token_endpoint_auth_method'] != 'none') {
         $client->pathSet('oauth.client_secret', $rand->secret());
         $response['client_secret'] = $client['oauth']['client_secret'];
         $response['client_secret_expires_at'] = 0;
     }
     $store = StoreManager::instance();
     $store->saveClient($client);
     $this->logger->log(LogLevel::INFO, 'Created dynamic client: ' . $client_id);
     $auth = new Authorization($client, $client, self::CLIENT_REGISTRATION_ACCESS_SCOPE);
     $store->saveAuth($auth);
     $token = $auth->issueAccessToken(array(self::CLIENT_REGISTRATION_ACCESS_SCOPE));
     $response['registration_access_token'] = $token['access_token'];
     $this->f3->status(201);
     $response->renderJSON();
 }
Пример #3
0
 /**
  * Displays the OpenID Connect configuration file for this installation.
  *
  */
 public function openid_configuration()
 {
     $mgr = ModuleManager::instance();
     header('Content-Type: application/json');
     header('Content-Disposition: inline; filename=openid-configuration');
     $scopes = $mgr->invokeAll('scopes');
     $jwt_signing_algs = AlgorithmFactory::getSupportedAlgs(Algorithm::SIGNATURE_ALGORITHM);
     $jwt_encryption_algs = AlgorithmFactory::getSupportedAlgs(Algorithm::KEY_ALGORITHM);
     $jwt_encryption_enc_algs = AlgorithmFactory::getSupportedAlgs(Algorithm::ENCRYPTION_ALGORITHM);
     $claims_supported = array('sub', 'iss', 'auth_time', 'acr');
     foreach ($scopes['oauth'] as $scope => $settings) {
         if (isset($settings['claims'])) {
             $claims_supporteds = array_merge($claims_supported, $settings['claims']);
         }
     }
     $token_endpoint_auth_methods_supported = array('client_secret_basic', 'client_secret_post');
     $config = array('issuer' => $this->getCanonicalHost(), 'authorization_endpoint' => $this->getCanonicalURL('@oauth_auth', '', 'https'), 'token_endpoint' => $this->getCanonicalURL('@oauth_token', '', 'https'), 'userinfo_endpoint' => $this->getCanonicalURL('@connect_userinfo', '', 'https'), 'jwks_uri' => $this->getCanonicalURL('@connect_jwks', '', 'https'), 'scopes_supported' => array_keys($scopes['oauth']), 'response_types_supported' => array('code', 'token', 'id_token', 'id_token token', 'code token', 'code id_token', 'code id_token token'), 'response_modes_supported' => Response::getResponseModesSupported(), 'grant_types_supported' => array('authorization_code', 'refresh_token'), 'acr_values_supported' => array(), 'subject_types_supported' => array('public', 'pairwise'), 'userinfo_signing_alg_values_supported' => $jwt_signing_algs, 'userinfo_encryption_alg_values_supported' => $jwt_encryption_algs, 'userinfo_encryption_enc_alg_values_supported' => $jwt_encryption_enc_algs, 'id_token_signing_alg_values_supported' => $jwt_signing_algs, 'id_token_encrpytion_alg_values_supported' => $jwt_encryption_algs, 'id_token_encrpytion_enc_alg_values_supported' => $jwt_encryption_enc_algs, 'request_object_signing_alg_values_supported' => array_merge($jwt_signing_algs, array('none')), 'request_object_encryption_alg_values_supported' => $jwt_encryption_algs, 'request_object_encryption_enc_alg_values_supported' => $jwt_encryption_enc_algs, 'token_endpoint_auth_methods_supported' => $token_endpoint_auth_methods_supported, 'claim_types_supported' => array('normal'), 'claims_supported' => $claims_supported, 'claims_parameter_supported' => true, 'request_parameter_supported' => true, 'request_uri_parameter_supported' => true, 'require_request_uri_registration' => false, 'service_documentation' => 'http://simpleid.koinic.net/docs/');
     $config = array_merge($config, $mgr->invokeAll('connectConfiguration'));
     print json_encode($config);
 }