Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Submitting an html-form with java

Tags:

java

forms

php

I'm trying to create a login app for a campus network. I've gotten pretty far but now I'm stuck.

I'm at a point where java returns me a page that contains a simple form that should auto submit:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">   
<body onload="document.forms[0].submit()">       
<noscript>     
    <p>      
        <strong>Note:</strong> Since your browser does not support JavaScript,                you must press the Continue button once to proceed.            
    </p>        
</noscript>                

<form action="url" method="post">
    <div> 
        <input type="hidden" name="RelayState" value="ss:mem:43141e4108638211a81427d145c7e9de"/>        

        <input type="hidden" name="SAMLResponse" value="base64string"/>         
    </div>    
    <noscript>          
        <div>    
            <input type="submit" value="Continue"/>      
        </div>     
    </noscript>     
</form>     
</body></html>

When I copy this string to an .html file and click on submit, it logs me in just fine. Now i'm trying to do this in java, so I extract RelayState and SAMLResponse and use the following code to submit:

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

String params = "RelayState="+relayState+"&SAMLResponse="+saml;
System.out.println(params.length());

urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length));
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2");


urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);

DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(params);
wr.flush();
wr.close();

InputStream in = new BufferedInputStream(urlConnection.getInputStream());

DataInputStream dis = new DataInputStream(new BufferedInputStream(in));

String fullPage = "";
String s;
while ((s = dis.readLine()) != null)
{
    fullPage += s;
}

urlConnection.disconnect();

This code returns a 500 - internal server error. What am I missing?

To test what was being sent, I changed the url to a simple print_r($_POST) and print_r(getAllHeaders()) and this is what I got:

//when I submit using java:
Array(    
    [Accept] => text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2    
    [Connection] => keep-alive    
    [Content-Length] => 14176    
    [Content-Type] => application/x-www-form-urlencoded    
    [Host] => xxx   
    [User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
)

Array(    
    [RelayState] => ss:mem:43141e4108638211a81427d145c7e9de
    [SAMLResponse] => base64string
)



//when I submit by copying the string to my browser and clicking submit
Array
(
    [Accept] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    [Accept-Encoding] => gzip, deflate
    [Accept-Language] => en-us,en;q=0.5
    [Connection] => keep-alive
    [Content-Length] => 14204
    [Content-Type] => application/x-www-form-urlencoded
    [DNT] => 1
    [Host] => xxx
    [User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
)
Array
(
    [RelayState] => ss:mem:43141e4108638211a81427d145c7e9de
    [SAMLResponse] => base64string
)

I notice that the content-length header isn't the same for the two cases, but I don't know why that is or if that has anything to do with it.

like image 348
Dauntless Avatar asked Nov 05 '22 04:11

Dauntless


1 Answers

If you have access to server logs it can help. Status 500 is thrown when internal server error happens. It means that you are doing something that cannot be handled by server successfully.

If you do not have access to server try the following. First, check again that your request sent from java is (almost) identical to one sent from browser. You can use WireShark for this.

If you think that everything is OK but it still does not work possible reason is that you are stateless. When browser arrives to the site first time it receives back session ID sent as special cookie. Cookies are sent in response header named Set-Cookie. Browser takes content of this header and sends it back as request header 'Cookie'. This is the difference between your application and browser.

Theoretically server should not fail on this request. It just should redirect you again to the login page. But it seems that there is a bug in server side: it just fails to handle your "wrong" request and throws exception.

BTW if you want to make things easier user HttpClient from jakarta.apache.org. It supports session full mode, so you do not have to deal with gory detail of HTTP protocol. But you can stand with regular HttpConnection too if you want. \

Good luck.

like image 151
AlexR Avatar answered Nov 07 '22 22:11

AlexR