/** * Builds the JOSE response. This will return one of the following: * * - A JSON encoded string, if {@link $signed_response_alg} and * {@link $encrypted_response_alg} are both null * - A signed JWT (JWS), if {@link $signed_response_alg} is set * - A JWE containing a nested JWT, if both {@link $signed_response_alg} * and {@link $encrypted_response_alg} are set * * @param SimpleJWT\Keys\KeySet $set the key set used to sign and/or * encrypt the token. If set to null, the default set of keys * configured for the client and the server are loaded * @return string the response body */ function buildJOSE($set = null) { $rand = new Random(); $typ = $this->getType(); if ($typ == 'json') { return json_encode($this->container); } if ($set == null) { $builder = new KeySetBuilder($client); $set = $builder->addClientSecret()->addClientPublicKeys()->addServerPrivateKeys()->toKeySet(); } $headers = array_merge($this->headers, array('alg' => $this->signed_response_alg)); $claims = array_merge($this->container, array('iss' => $this->issuer, 'aud' => $this->client->getStoreID(), 'jti' => $rand->id())); $jwt = new JWT($headers, $claims); try { $token = $jwt->encode($set); } catch (CryptException $e) { return null; } if ($typ == 'jwt') { return $token; } $headers = array('alg' => $this->encrypted_response_alg, 'enc' => $this->encrypted_response_enc, 'cty' => 'JWT'); $jwe = new JWE($headers, $token); try { return $jwe->encrypt($set); } catch (CryptException $e) { return null; } }
/** * @see SimpleID\API\OAuthHooks::oAuthResolveAuthRequestHook() */ public function oAuthResolveAuthRequestHook($request, $response) { $store = StoreManager::instance(); $web = Web::instance(); // 1. Check if request_uri parameter is present. If so, fetch the JWT // from this URL and place it in the request parameter if (isset($request['request_uri'])) { $this->logger->log(LogLevel::INFO, 'OpenID request object: getting object from ' . $request['request_uri']); $parts = parse_url($request['request_uri']); $http_response = new HTTPResponse($web->request($request['request_uri'], array('headers' => array('Accept' => 'application/jwt,text/plain,application/octet-stream')))); if ($http_response->isHTTPError()) { $this->logger->log(LogLevel::ERROR, 'Cannot retrieve request file from request_uri:' . $request['request_uri']); $response->setError('invalid_request_uri', 'cannot retrieve request file from request_uri'); return; } $request['request'] = $http_response->getBody(); unset($request['request_uri']); } // 2. Check if the request parameter is present. If so, we are dealing with // an additional OpenID Connect request object. We need to parse this object if (isset($request['request'])) { $this->logger->log(LogLevel::INFO, 'OpenID request object token: ' . $request['request']); $client = $store->loadClient($request['client_id'], 'SimpleID\\Protocols\\OAuth\\OAuthClient'); if (!isset($client['connect']['request_object_signing_alg'])) { $this->logger->log(LogLevel::ERROR, 'Invalid OpenID request object: signature algorithm not registered'); $response->setError('invalid_openid_request_object', 'signature algorithm not registered'); return; } $jwt_alg = isset($client['connect']['request_object_signing_alg']) ? $client['connect']['request_object_signing_alg'] : null; $jwe_alg = isset($client['connect']['request_object_encryption_alg']) ? $client['connect']['request_object_encryption_alg'] : null; $builder = new KeySetBuilder($client); $set = $builder->addClientSecret()->addClientPublicKeys()->addServerPrivateKeys()->toKeySet(); try { AlgorithmFactory::addNoneAlg(); $helper = new Helper($request['request']); $jwt = $helper->getJWTObject($set, $jwe_alg, $jwt_alg); $request->loadData($jwt->getClaims()); } catch (\UnexpectedValueException $e) { $this->logger->log(LogLevel::ERROR, 'Invalid OpenID request object: ' . $e->getMessage()); $response->setError('invalid_openid_request_object', $e->getMessage()); return; } } AlgorithmFactory::removeNoneAlg(); // 3. nonce if ($request->paramContains('scope', 'openid') && $request->paramContains('response_type', 'token') && !isset($request['nonce'])) { $this->logger->log(LogLevel::ERROR, 'Protocol Error: nonce not set when using implicit flow'); $response->setError('invalid_request', 'nonce not set when using implicit flow')->renderRedirect(); return; } }