Имитация входа в Discourse SSO через php curl

Я занимаюсь интеграцией Discourse в нашу платформу (используя iframe) и пытаюсь понять, что я делаю неправильно, и не могу заставить SSO аутентифицировать своих пользователей.

Я работаю над symfony 1.4, и у меня есть действие, которое соответствует как логике отображения страницы (содержащей iframe), так и логике входа пользователей.

public function executeViewDiscussionForum(sfWebRequest $request){        

    $requestIsInternal  = $request->getParameter('isInternal');

    if($requestIsInternal==='1'){
        //====Discourse will redirect here again with the payload parameters
        $response = DiscourseAuthDriver::makeCurlRequest('http://****.****.com:8080');
    }

    $url = parse_url($response['Location']);
    $cookie = $response['Set-Cookie'];
    parse_str($url['query'], $params);
    $sso = $params['sso'];
    $signature = $params['sig'];

    // load the payload passed in by Discourse
    $payload = $sso;

    $ssoHelper = new SSOHelper();
    // this should be the same in your code and in your Discourse settings:
    $secret = '****';
    $ssoHelper->setSecret( $secret );



    // validate the payload
    if (!($ssoHelper->validatePayload($payload,$signature))) {
        // invaild, deny
        $this->redirect404();
    }

    $nonce = $ssoHelper->getNonce($payload);

    // Insert your user authentication code here ...

    // Required and must be unique to your application
    $userId = $this->currentUser->id;

    // Required and must be consistent with your application
    $userEmail = $this->currentUser->getEmailAddress();

    // Optional - if you don't set these, Discourse will generate suggestions
    // based on the email address

    $extraParameters = array(
        'username' => $this->currentUser->getUsername(),
        'name'     => $this->currentUser->getFullname()
    );


    // build query string and redirect back to the Discourse site
    $query = $ssoHelper->getSignInString($nonce, $userId, $userEmail, $extraParameters);
    DiscourseAuthDriver::makeCurlRequest('http://*****.***.com:8080/session/sso_login?' . $query, $cookie); 
}

Класс SSOHelper, который я использую, находится здесь

И DiscourseAuthDriver::makeCurlRequest выглядит следующим образом:

public static function makeCurlRequest($url, $cookie=null){
        $ch = curl_init($url);
        if($cookie){
            curl_setopt($ch, CURLOPT_HTTPHEADER, array("Set-Cookie: ".$cookie));
            curl_setopt($ch, CURLOPT_NOBODY, 1);
        }
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0"); // Necessary. The server checks for a valid User-Agent.        
        $response = curl_exec($ch);
        $header = $response;
        $header = self::get_headers_from_curl_response($header);

        curl_close($ch);
        return $header[1];
    }

Если у меня не включен SSO, я могу видеть, что основная страница дискурса загружается очень хорошо в моем iframe.

Логика вышеизложенного заключалась в том, что с помощью curl я могу по существу имитировать процесс входа в систему, а затем обслуживать зарегистрированную страницу в iframe, но это, похоже, не сокращает ее, даже если я вручную перехожу к URL-адресу входа с хешированными параметрами. и все получаю следующую ошибку:

"Account login timed out, please try logging in again"

Я проверил другие возможные ответы, а также свои настройки, и у меня не установлен параметр утверждения, поэтому я подумал, что это может быть связано с тем, что информация о сеансе не передается при запросе входа в систему, но даже после добавления, что это не работает.

Может ли кто-нибудь увидеть, что с этим не так, или выявить какие-либо недостатки в логике?


person mixkat    schedule 03.09.2015    source источник


Ответы (1)


Я не знаю как, но по какой-то причине URL-адрес запроса сегодня работает нормально, и он аутентифицирует моих пользователей.

Чтобы не возиться с заголовками и не иметь проблем с iframe и т. д., я сделал так, чтобы он использовал curl только для получения исходного URL-адреса, содержащего данные полезной нагрузки.

Как только я их получаю, я обрабатываю и создаю новый запрос на основе заданной полезной нагрузки, а затем передаю их скрытому фрейму, который делает запрос на вход (т.е. из браузера), затем javascript берет на себя удаление этого скрытого фрейма и загружает новый тот, который загружает главную страницу дискурса с уже зарегистрированным пользователем.

Надеюсь, это поможет кому-то в будущем.

person mixkat    schedule 04.09.2015