# httpclient kann sich nicht auf asp.net Seite anmelden



## mwflipper (5. Mrz 2009)

Hallo,
ich versuche seit Wochen, mit per HttpClient auf der Seite geocaching.com anzumelden. Die Seite läuft auf einem Asp.net Server und erwartet neben den LoginDaten auch immer einen ViewState. Leider erscheint als Antwort auf meinen Loginversuch zwar der Statuscode "200 OK", aber im Body ist zu erkennen, dass mein Login fehlgeschlagen ist. Ich vermute, dass es mit dem Viewstate zu tun hat. Meine Frage deshalb: Wie kann ich in Java (httpclient) einen Asp.net-Viewstate parsen, editieren und zurücksenden. Mit folgendem Code habe ich den Login versucht. Der angegebene Benutzer ist ein real existierender, d.h der Code kann zum Testen so verwendet werden.
[HIGHLIGHT="Java"]package httpclient;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.InputTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import sun.misc.BASE64Decoder;

public class Test {
	static final String hostURI = "http://www.geocaching.com";


	public static void main(String[] args) {
		int status;

		String proxyHost = null;
		int proxyPort = 8080;
		String userName = "cacheuser";
		String userPassword = "cacheclient";
		String viewStateValue = "";
		String LOGON_SITE = "http://www.geocaching.com/login/default.aspx";

		HttpClient client = new HttpClient();
		HostConfiguration hostConfig = new HostConfiguration();
		if (null != proxyHost) {
			hostConfig.setProxy(proxyHost, proxyPort);
		}
		hostConfig.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
		client.setHostConfiguration(hostConfig);

		client.getParams().setParameter("http.socket.timeout", new Integer(10000));

		client.getParams().setParameter("http.protocol.content-charset", "UTF-8");

		client.getParams().setBooleanParameter("http.protocol.single-cookie-header", true);

		client.getParams().setParameter("http.useragent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)");

		client.getParams().setCookiePolicy(CookiePolicy.RFC_2109);
		GetMethod getMethodInfoPage = new GetMethod(LOGON_SITE);		

		System.out.println("\n" + "About to make call for getMethodInfoPage connection attempt");
		try {
			status = client.executeMethod(getMethodInfoPage);

			Parser parser = null;
			try {

				parser = new Parser(new Lexer(getMethodInfoPage.getResponseBodyAsString()));
				InputTag node = (InputTag) parser.parse(new HasAttributeFilter("name", "__VIEWSTATE")).elementAt(0);
				viewStateValue += node.getAttribute("value");
				BASE64Decoder decoder = new BASE64Decoder();

				String decodedViewstate = new String(decoder.decodeBuffer(viewStateValue));

				System.err.println("Encoded viewstate :" + decodedViewstate);
				System.out.println("End of getting Initial Page"); // there may not be a HEAD tag

			} catch (IOException ex2) {
				ex2.printStackTrace();
			} catch (ParserException ex2) {
				ex2.printStackTrace();
			}
			Cookie[] cookies = client.getState().getCookies();
			for (int i = 0; i < cookies.length; i++) {
				Cookie cookie = cookies_;
				System.out.println("Cookie: " + cookie.getName() + ", Value: " + cookie.getValue()
						+ ", IsPersistent?: " + cookie.isPersistent() + ", Expiry Date: " + cookie.getExpiryDate()
						+ ", Comment: " + cookie.getComment());
			}
			getMethodInfoPage.releaseConnection();
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		// ******************** now preparing to do POST **********************

		NameValuePair[] logindata = new NameValuePair[4];

		logindata[0] = new NameValuePair("myUsername", userName);
		logindata[1] = new NameValuePair("myPassword", userPassword);
		logindata[2] = new NameValuePair("__VIEWSTATE", viewStateValue);
		logindata[3] = new NameValuePair("cookie", "on");

		PostMethod postMethodLoginPage = new PostMethod(LOGON_SITE);

		postMethodLoginPage.addRequestHeader("Connection", "Keep-Alive");

		client.getParams().setCookiePolicy(CookiePolicy.RFC_2109);

		postMethodLoginPage.setRequestBody(logindata);
		String content = null;
		try {
			status = client.executeMethod(postMethodLoginPage);
			content = postMethodLoginPage.getResponseBodyAsString();
			writeFile(content);
			postMethodLoginPage.releaseConnection();
		} catch (IOException ex1) {
			ex1.printStackTrace();
		}
		Cookie[] cookies = client.getState().getCookies();
		for (int i = 0; i < cookies.length; i++) {
			Cookie cookie = cookies;
			System.out.println("Cookie: " + cookie.getName() + ", Value: " + cookie.getValue() + ", IsPersistent?: "
					+ cookie.isPersistent() + ", Expiry Date: " + cookie.getExpiryDate() + ", Comment: "
					+ cookie.getComment());
		}
		try {
			Parser parser = new Parser(new Lexer(content));
			NodeList loginPanelList = parser.parse(new HasAttributeFilter("id", "LoginPanel"));
			if (loginPanelList.size() > 0) {
				Div node = (Div) loginPanelList.elementAt(0);
				if (null != node) {
					System.err.println("login failed");
				}
			} else {
				System.out.println("login ends successfully");
			}
		} catch (ParserException e) {
			e.printStackTrace();
		}
	}

	public static void writeFile(String content) {

		File testHtml = new File("test.html");
		if (null == content) {
			if (testHtml.exists()) {
				testHtml.delete();
			}
		}
		try {
			FileWriter fw = new FileWriter(testHtml);
			fw.append(content);
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}[/HIGHLIGHT]_


----------



## snady (20. Apr 2009)

Hey!

Ich hatte mich auch gerade mit dem Thema beschäftigt und bin über deinen Beitrag gestolpert. Geändert wurde einerseits die Reihenfolge der Parameter, sowie der letzte Parameter von "cookie"//"on" auf "Button1"//"Login". Alle weiteren Änderungen im Code waren notwendig weil ich vermutlich eine andere Version der Apache Bibliotheken nutze.


```
package org.foo.geocaching;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.InputTag;
import org.htmlparser.util.NodeList;

import sun.misc.BASE64Decoder;

public class GCConnection {

	private static final String LOGON_SITE = "http://www.geocaching.com/login/default.aspx";
	
	private String viewStateValue = "";    
	private DefaultHttpClient client;
    
	private String username;
	private String password;

	public GCConnection(String username, String password) throws Exception {
		if(username == null || password == null || username.equals("") || password.equals("")){
			throw new Exception("Please specify a non empty username and password to create a Connection to geocaching.com");
		}
		this.username = username;
		this.password = password;
	}

	public boolean login() throws Exception, IOException {
		client = new DefaultHttpClient();
        
		client.getCookieStore().clear();        
        client.getParams().setParameter("http.protocol.content-charset", "UTF-8");        
        client.getParams().setBooleanParameter("http.protocol.single-cookie-header", true); 
        client.getParams().setParameter("http.useragent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)");
        
        // Phase 1: Get the Logon Website/Form and extract the viewstate.
        HttpGet httpget = new HttpGet(LOGON_SITE);        
		Parser parser = null; 
		HttpResponse response = client.execute(httpget);
	    HttpEntity entity = response.getEntity();
	    String res = getResponseBodyAsString(entity);
	    entity.consumeContent();
	    
	    parser = new Parser(new Lexer(res));
	    InputTag node = (InputTag) parser.parse(new HasAttributeFilter("name", "__VIEWSTATE")).elementAt(0);
	    viewStateValue += node.getAttribute("value");
		BASE64Decoder decoder = new BASE64Decoder();
		 
        // Phase 2: Post the Login data 
        List <NameValuePair> nvps = new ArrayList <NameValuePair>();        
        nvps.add(new BasicNameValuePair("__VIEWSTATE", viewStateValue));
        nvps.add(new BasicNameValuePair("myUsername", username));
        nvps.add(new BasicNameValuePair("myPassword", password));
        nvps.add(new BasicNameValuePair("Button1", "Login"));
        
        HttpPost httpost = new HttpPost(LOGON_SITE);
        
        httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        httpost.setHeader("Connection", "Keep-Alive");
         
        response = client.execute(httpost);
        entity = response.getEntity();

    	String content = getResponseBodyAsString(entity);
        entity.consumeContent();
        parser = new Parser(new Lexer(content));
        NodeList loginPanelList = parser.parse(new HasAttributeFilter("id", "LoginPanel"));
        if (loginPanelList.size() > 0) {
            Div div = (Div) loginPanelList.elementAt(0);
            if (null != div) {
                return false;
            }
        } else {
        	return true;
        }
        return false;
	}
	
	public static String getResponseBodyAsString(HttpEntity entity) throws IllegalStateException, IOException{
    	InputStream in = entity.getContent();
    	long len = entity.getContentLength();
    	if(len > 0){
			byte [] buffer = new byte [(int) entity.getContentLength()];
			int i = in.read();
			int j = 0;
			while(true){
				if(i != -1){
					buffer[j] = (byte) i;
					i = in.read();
					j++;
				} else {
					break;
				}			
			}
			String s = new String(buffer);
			return s;
    	} else {
    		return "";
    	}
    }

	/**
	 * 
	 * @return Returns a List of caches by their URL at geocaching.com. Use entries from this List to query
	 * geocaching.com on certain caches.
	 */
	public List<String> getCacheList() {
		
		
		return null;
	}

	public String getCache(String url) throws ClientProtocolException, IOException {
		HttpGet httpget = new HttpGet(url);
		HttpResponse response = client.execute(httpget);
		HttpEntity entity = response.getEntity();

		String data = getResponseBodyAsString(entity);
		entity.consumeContent();

		return data;
	}
	
	public void finalize(){
		client.getConnectionManager().shutdown();
	}
	

	
}
```

Viel Erfolg
snady


----------



## sparrow (20. Apr 2009)

Ich habe damals den kompletten Dialog mit der Webseite selber geschrieben, also nur Klassen der Standard-Bibliothek verwendet. Das geht eigentlich ganz gut.
Also Request selber zusammen gestellt, über eine URLConnection rüber geschickt und die Antwort dann geparst und verarbeitet.
Steht allerdings in keinem Verhältnis zu den nur 15 Euro pro Jahr für eine Premiummitgliedschaft, und damit gibts PocketQueries


----------

