Perl / cURL中的脚本,无法通过带有两个提交和click()加载的HTML表单



我正在制作一个脚本,其中的主要部分是通过一个名为Feide的系统登录。我使用过Perl和cURL,并且我设法实际登录并制作了会话cookie,但是由于cURL不支持Javascript,我必须按一个按钮("由于您的浏览器不支持JavaScript,您必须按一次下面的按钮才能继续。不幸的是,形式很奇怪。当我运行脚本时,它只是将我重定向回同一站点,我不知道为什么。这是 HTML:

<body onload="document.getElementsByTagName('input')[0].click();">
<noscript>
    <p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the button below once to proceed.</p> 
</noscript> 
<form method="post" action="https://innsida.ntnu.no/c/portal/login">
<!-- Need to add this element and call click method, because calling submit()
on the form causes failed submission if the form has another element with name or id of submit.
See: https://developer.mozilla.org/en/DOM/form.submit#Specification -->
    <input type="submit" style="display:none;" />
    <input type="hidden" name="SAMLResponse" value="[very long value]" />
    <input type="hidden" name="RelayState" value="https://innsida.ntnu.no" />
        <noscript>
            <input type="submit" value="Submit" />
        </noscript>
</form>
</body>

也许我错过了什么,但我似乎无法以正确的方式提交此表格。这是我的脚本:

    use strict;
    use warnings;
    use WWW::Curl::Easy;
    use WWW::Curl::Multi;
    use WWW::Curl::Share;
    use WWW::Curl::Form;
    use DBI;

    my $dbh = DBI->connect('DBI:mysql:feide', '[myusername]', '[mypassword]') || die "Could not connect to database: $DBI::errstr";

    my $username = $dbh->prepare('SELECT username FROM credentials WHERE id=1');
     my $password = $dbh->prepare('SELECT password FROM credentials WHERE id=1');
     my $curl = WWW::Curl::Easy-> new;
     $curl->setopt(CURLOPT_HEADER, 1);
     #Make sure redirects don't fuck me
     $curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
     #Where cookies are saved 
     $curl->setopt(CURLOPT_COOKIEJAR, 'cookies.txt');
     #Where cookies are read from
     $curl->setopt(CURLOPT_COOKIEFILE, 'cookies.txt');
     $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
     $curl->setopt(CURLOPT_URL, 'https://idp.feide.no/simplesaml/module.php/feide/login.php?asLen=225&AuthState=_3f669be75024644be95e67ec6845222aefa860db98%3Ahttps%3A%2F%2Fidp.feide.no%2Fsimplesaml%2Fsaml2%2Fidp%2FSSOService.php%3Fspentityid%3Durn%253Amace%253Afeide.no%253Aservices%253Ano.ntnu.innsida%26cookieTime%3D1456232047%26RelayState%3Dhttps%253A%252F%252Finnsida.ntnu.no');
     my $response_body;
     $curl->setopt(CURLOPT_WRITEDATA,$response_body);
    my $retcode = $curl->perform;
    my $checkSession = 0;
    my @split;
    #check if there is a current session
    if($response_body =~ /"AuthState" value="/){
     @split = split /"AuthState" value="/, $response_body;
     my @authState = split /"/, $split[1];
     #make a form for a POST-request
     my $curlf = WWW::Curl::Form->new;
     $checkSession = 1;
     $curlf->formadd("feidename", $username);
     $curlf->formadd("password", $password);
     $curlf->formadd("asLen", "225");
     $curlf->formadd("AuthState", $authState[0]);
     $curlf->formadd("org", "ntnu.no"); 
     $curl->setopt(CURLOPT_HTTPPOST, $curlf);

     $retcode = $curl->perform;
    }


    if ($checkSession){
    @split = ();
    @split = split /"SAMLResponse" value="/, $response_body;
    }
    else{
     my @split = split /"SAMLResponse" value="/, $response_body;
    }
    my @SAML = split /"/, $split[1];
    #Here I try to create a new form, where I add what 
    #I believe to be the correct values. They don't work, 
    #and I get redirected back to the "press the button"-website
    my $noJS = WWW::Curl::Form->new;
    $noJS->formadd("SAMLResponse", $SAML[0]);
    $noJS->formadd("RelayState", "https://innsida.ntnu.no");
    $curl->setopt(CURLOPT_HTTPPOST, $noJS);
    $curl->setopt(CURLOPT_URL, 'https://innsida.ntnu.no/c/portal/login');
    $curl->perform;

    print $response_body, "n";

当然,我不能在这里把我的用户名和密码放到费德,所以你们不能自己尝试一下。希望无论如何有人能看到解决方案。

我将在最后发布整个HTML代码(脚本的输出),以防有人感兴趣:

     HTTP/1.1 302 Found
     Date: Wed, 24 Feb 2016 10:35:10 GMT
     X-Content-Type-Options: nosniff
     X-Frame-Options: SAMEORIGIN
     X-XSS-Protection: 1
     Pragma: no-cache
     Cache-Control: no-cache, no-store
     Expires: Thu, 01 Jan 1970 00:00:00 GMT
     Location: https://idp.feide.no/simplesaml/saml2/idp/SSOService.php?SAMLRequest=[removed for security purposes]
     Content-Length: 0
    HTTP/1.1 200 OK
    Date: Wed, 24 Feb 2016 10:35:10 GMT
    Server: Apache/2.2.24 (Unix)
    X-Powered-By: PHP/5.3.26
    Content-Length: 7866
    Content-Type: text/html
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>POST data</title>
    </head>
    <body onload="document.getElementsByTagName('input')[0].click();">
<noscript>
    <p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the button below once to proceed.</p> 
</noscript> 
<form method="post" action="https://innsida.ntnu.no/c/portal/login">
<!-- Need to add this element and call click method, because calling submit()
on the form causes failed submission if the form has another element with name or id of submit.
See: https://developer.mozilla.org/en/DOM/form.submit#Specification -->
<input type="submit" style="display:none;" />
    <input type="hidden" name="SAMLResponse" value="[ridiculously long value]==" />
    <input type="hidden" name="RelayState" value="https://innsida.ntnu.no" />
            <noscript>
        <input type="submit" value="Submit" />
            </noscript>
        </form>
    </body>
    </html>

如果我遗漏了什么,请告诉我,我会尽力提供。

编辑:当我在浏览器中关闭Javascript并复制为cUrl时,我得到了这个:

curl 'https://innsida.ntnu.no/c/portal/login' 
-H 'Host: innsida.ntnu.no' 
-H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' 
-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Referer: https://idp.feide.no/simplesaml/module.php/feide/login.php?asLen=225&AuthState= [removed]https%253A%252F%252Finnsida.ntnu.no' 
-H 'Cookie: COOKIE_SUPPORT=true; GUEST_LANGUAGE_ID=nb_NO; JSESSIONID=[removed].innsidaprod01; LFR_SESSION_STATE_111384=[removed]; LFR_SESSION_STATE_10135=[removed] -H 'Connection: keep-alive' 
--data 'SAMLResponse=[long value]&RelayState=https%3A%2F%2Finnsida.ntnu.no'

我怀疑表单未验证,因此您将被重定向到同一表单。如果它们没有任何特殊类型的脚本保护,您应该能够通过转到浏览器上的Network Tab Developer Tools来创建有效的请求,然后选择 Copy as cURL 。这将为您提供根据有效请求设置的所有选项的列表。

这应该可以帮助您绕过重定向循环。

最新更新