$dispatcher = new Authorization\Dispatcher();
$dispatcher->setStateManager($stateManager);
if (!isset($_GET['redirect'])) {
    $request = new Authorization\Request($clientInfo, 'code', 'openid profile email');
    $uri = $dispatcher->createAuthorizationRequestUri($request);
    _dump($uri);
    printf("<pre>%s</pre><br>", $uri);
    printf("<a href=\"%s\">Login</a>", $uri);
} else {
    try {
        $response = $dispatcher->getAuthorizationResponse();
        printf("OK<br>Code: %s<br>State: %s<br>", $response->getCode(), $response->getState());
        $tokenRequest = new Token\Request();
        $tokenRequest->fromArray(array('client_info' => $clientInfo, 'code' => $response->getCode(), 'grant_type' => 'authorization_code'));
        $httpClient = _createHttpClient();
        $tokenDispatcher = new Token\Dispatcher($httpClient);
        try {
            $tokenResponse = $tokenDispatcher->sendTokenRequest($tokenRequest);
            _dump($tokenResponse);
            printf("Access token: %s<br>", $tokenResponse->getAccessToken());
            $userInfoRequest = new UserInfo\Request();
            $userInfoRequest->setAccessToken($tokenResponse->getAccessToken());
            $userInfoRequest->setClientInfo($clientInfo);
            $userInfoDispatcher = new UserInfo\Dispatcher($httpClient);
            try {
                $userInfoResponse = $userInfoDispatcher->sendUserInfoRequest($userInfoRequest);
                _dump($userInfoResponse->getClaims());
                printf("User info: %s", \Zend\Json\Json::encode($userInfoResponse->getClaims(), \Zend\Json\Json::TYPE_ARRAY));
            } catch (\Exception $e) {
                printf("Error: [%s] %s<br>", get_class($e), $e->getMessage());
                _dump("{$e}");
 /**
  * Resume authentication process.
  *
  * This function resumes the authentication process after the user has
  * entered his or her credentials.
  *
  * @param array &$state  The authentication state.
  */
 public static function resume()
 {
     $request = Request::fromString($_SERVER['REQUEST_METHOD'] . ' ' . self::requesturi());
     if (!($stateId = $request->getQuery('state'))) {
         throw new SimpleSAML_Error_BadRequest('Missing "state" parameter.');
     }
     $state = SimpleSAML_Auth_State::loadState($stateId, 'openidconnect:Connect');
     /*
      * Now we have the $state-array, and can use it to locate the authentication
      * source.
      */
     $source = SimpleSAML_Auth_Source::getById($state['openidconnect:AuthID']);
     if ($source === NULL) {
         /*
          * The only way this should fail is if we remove or rename the authentication source
          * while the user is at the login page.
          */
         throw new SimpleSAML_Error_Exception('Could not find authentication source.');
     }
     /*
      * Make sure that we haven't switched the source type while the
      * user was at the authentication page. This can only happen if we
      * change config/authsources.php while an user is logging in.
      */
     if (!$source instanceof self) {
         throw new SimpleSAML_Error_Exception('Authentication source type changed.');
     }
     // The library has its own state manager but we're using SSP's.
     // We've already validated the state, so let's get the token.
     $tokenDispatcher = new Dispatcher();
     $tokenRequest = new TokenRequest();
     $clientInfo = new ClientInfo();
     $clientInfo->fromArray(reset($source->getConfig()));
     $tokenRequest->setClientInfo($clientInfo);
     $tokenRequest->setCode($request->getQuery('code'));
     $tokenRequest->setGrantType('authorization_code');
     $tokenDispatcher->setOptions(['http_options' => ['sslcapath' => $source->sslcapath]]);
     $tokenResponse = $tokenDispatcher->sendTokenRequest($tokenRequest);
     $userDispatcher = new InfoDispatcher();
     $userDispatcher->setOptions(['http_options' => ['sslcapath' => $source->sslcapath]]);
     $infoRequest = new InfoRequest();
     $infoRequest->setClientInfo($clientInfo);
     $infoRequest->setAccessToken($tokenResponse->getAccessToken());
     try {
         $infoResponse = $userDispatcher->sendUserInfoRequest($infoRequest);
         $user = $infoResponse->getClaims();
     } catch (Exception $e) {
         /*
          * The user isn't authenticated.
          *
          * Here we simply throw an exception, but we could also redirect the user back to the
          * login page.
          */
         throw new SimpleSAML_Error_Exception('User not authenticated after login attempt.', $e->getCode(), $e);
     }
     /*
      * So, we have a valid user. Time to resume the authentication process where we
      * paused it in the authenticate()-function above.
      */
     $state['Attributes'] = self::getAttributes($user);
     SimpleSAML_Auth_Source::completeAuth($state);
     /*
      * The completeAuth-function never returns, so we never get this far.
      */
     assert('FALSE');
 }