Avatar billede cybershah Nybegynder
08. oktober 2012 - 11:15 Der er 6 kommentarer og
1 løsning

Loade HTML indhold fra en form-based authenticated URL

Hej

Jeg har brugt mange timer på at finde et brugbart eksempel, men desværre uden held.

Koden skal kunne logge ind på en password beskyttet URL (med egen konto) og læse alt HTML koden fra websiden. Siden er aspx og bruger form-based authentication.

Jeg har en nogenlunde ide af hvad koden skal gøre og er af den overbevisning at Apache httpClient vil være en store hjælp (i stedet for HTML parsing).

Er der nogen, som har et kode eksempel eller link til noget relevante tutorials? Alternative løsninger er også velkommen.
Avatar billede arne_v Ekspert
08. oktober 2012 - 15:29 #1
HttpClient er fin

grundliggende submitter du login credential til login URL og henter derefter den side du vil have
Avatar billede arne_v Ekspert
08. oktober 2012 - 15:30 #2
eksempel:

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class Login {
    private HttpClient client;
    public Login() {
        client = new DefaultHttpClient();
    }
    public void login(String url, String userField, String userValue, String passField, String passValue) throws Exception {
        List<NameValuePair> nvp = new ArrayList<NameValuePair>();
        nvp.add(new BasicNameValuePair(userField, userValue));
        nvp.add(new BasicNameValuePair(passField, passValue));
        post(url, nvp);
    }
    public String get(String url) throws Exception {
        HttpGet met = new HttpGet(url);
        return EntityUtils.toString(client.execute(met).getEntity());
    }
    public String post(String url, List<NameValuePair> nvp) throws Exception {
        HttpPost met = new HttpPost(url);
        if (nvp != null) {
            met.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
        }
        return EntityUtils.toString(client.execute(met).getEntity());
    }
    public static void main(String[] args) throws Exception {
        Login lgi = new Login();
        lgi.get("http://localhost:8080/login/open/test.jsp");
        lgi.login("http://localhost:8080/login/j_security_check", "j_username", "userarne", "j_password", "xxxxxx");
        System.out.println(lgi.get("http://localhost:8080/login/open/test.jsp"));
    }
}
Avatar billede arne_v Ekspert
08. oktober 2012 - 15:30 #3
Men ASP.NET web forms er lidt tricky.

Du vil vaere noedt til at hente login siden foerst og submitte login inkl. de hidden fields der er i den!
Avatar billede cybershah Nybegynder
09. oktober 2012 - 10:11 #4
Tak, jeg tester og vender tilbage :)
Avatar billede cybershah Nybegynder
15. oktober 2012 - 17:16 #5
Hej

Jeg har taget følgende hidden fields med:

<input type="hidden" name="__EVENTTARGET"
<input type="hidden" name="__EVENTARGUMENT" 
<input type="hidden" name="__VIEWSTATE" 
<input type="hidden" name="__EVENTVALIDATION"

Ved du om der er flere felter der skal med?

De to første hidden fields har ingen ting i Value, men sidste to (viewstate og eventvalidation) har hver unikke værdier, som tages med som parametre i login metoden, hvilken er ændret til:

public void login(String url, String userField, String userValue, String passField, String passValue, String eventtargetField, String eventtargetValue, String eventargumentField, String eventargumentValue, String viewstateField, String viewstateValue, String eventvalidationField, String eventvalidationValue)

throws Exception {
       
List<NameValuePair> nvp = new ArrayList<NameValuePair>();
nvp.add(new BasicNameValuePair(userField, userValue));
nvp.add(new BasicNameValuePair(passField, passValue));
       
nvp.add(new BasicNameValuePair(eventtargetField, eventtargetValue));
nvp.add(new BasicNameValuePair(eventargumentField, eventargumentValue));

nvp.add(new BasicNameValuePair(viewstateField, viewstateValue));
nvp.add(new BasicNameValuePair(eventvalidationField, eventvalidationValue));
       
post(url, nvp);
}

Men jeg får stadig kun login siden, når jeg kører get metoden, så det er ikke helt lykkedes endnu.

Btw,
HTTP.UTF_8 er deprecated, så den er ændret til HTTP.DEF_CONTENT_CHARSET
Avatar billede cybershah Nybegynder
17. oktober 2012 - 14:05 #6
Hej igen

Så har jeg løst problemet vha. jsoup. Man kan sikkert også programmere videre til en løsning via din model, men jeg fandt ud af at request/response cookierne skal med og her har jsoup sørget for en ret dækkende API. 

Det skal så også siges at samtlige hidden fields skal med og her er den mest tricky af dem alle sammen eventtarget, da dennes værdi skal være navnet på formets submit knap!

Jeg fik også store hjælp af firefox add-on "LIVE HTTP Headers"...

Da det var dit svar, som egentlig hjalp mig videre, vil jeg gerne give dig de 60 points. Så smid lige et svar...

MVH
Shah'en ;)
Avatar billede arne_v Ekspert
17. oktober 2012 - 16:49 #7
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester