So bekommt man schon mal eine Seite durch den Proxy, fehlt nur noch der HTTPS-Part und die Antwort (die zig Versionen des Daily-Dilbert-Agenten nutzen teilweise auch diese Funktionalität)
Dim WinHttpReq As Variant
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
'HttpRequest SetCredentials flags
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
Const HTTPREQUEST_PROXYSETTING_PROXY = 2
Const AutoLogonPolicy_Always = 0
'Specify the target resource.
Call WinHttpReq.open( "GET", "http://www.heise.de", False )
'Set credentials for server.
'Call WinHttpReq.SetCredentials( "User Name", "Password", HTTPREQUEST_SETCREDENTIALS_FOR_SERVER)
'It might also be necessary to supply credentials
' to the proxy if you connect to the Internet
' through a proxy that requires authentication.
Call WinHTTPReq.SetProxy(HTTPREQUEST_PROXYSETTING_PROXY, "myproxy:8080")
WinHTTPReq.SetAutoLogonPolicy AutoLogonPolicy_Always
' Send a request to the server and wait for
' a response.
Call WinHttpReq.send( )
' Display the results of the request.
Print WinHttpReq.ResponseText
Die Implementierung von SSL steht hier http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winhttp/http/ssl_in_winhttp.asp. Das schau ich mir aber erst an, wenn ich das wirklich brauchen sollte...
Da ich mich auch gerade mit dem Zeugs beschäftige. Hier ein kleines und sehr einfaches Beispiel mit jakarta.httpClient. Beinhaltet Proxy Authentifizierung.
import java.io.IOException;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
public class Simple {
/**
*
*/
public static void main(String[] args) {
HttpClient httpclient = new HttpClient();
client.getParams().setAuthenticationPreemptive(true); // WICHTIG!!!!
httpclient.getHostConfiguration().setProxy("proxy", port);
Credentials defaultcreds = new UsernamePasswordCredentials("myProxyName", "myProxyPassword");
httpclient.getState().setProxyCredentials(AuthScope.ANY, defaultcreds);
GetMethod httpget = new GetMethod("http://www.yahoo.de/");
try {
try {
httpclient.executeMethod(httpget);
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(httpget.getStatusLine());
try {
System.out.println(httpget.getResponseBodyAsString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} finally {
httpget.releaseConnection();
}
}
}
Als jars im Classpath müssen sein:
- commons-codec-1.2.jar
- commons-httpclient-3.0.jar
- commons-logging.jar (von commons-logging1.0.3).
Das ganze commons Zeugs gibt es hier:
http://jakarta.apache.org/commons/
Es gilt die Regel: Hast du 1 commons Projekt, braucht das mindestens 2 andere ;D
Diese Dependencies scheinen jetzt hier zu stehen: http://jakarta.apache.org/commons/httpclient/dependencies.html
Es ist das erste, nach dem ich Ausschau halte.
Ich hab heute morgen mit curl rumgehampelt. Ein php Skript vom Hersteller hat das benutzt.
http://curl.haxx.se/ (interessant. Eine Art http Kommandozeilen-Tool).
Mit diesem curl Befehl sendet man einen http-Post (!!) Request gegen einen Server auf SSL, mißachtet, dass man die CA nicht hat (-k) und authentifiziert sich gleichzeitig gegen den Server und im authentifizierenden Proxy in der Firma:
D:\toolsMS\curl-7.15.1>curl -U meinProxyUser:meinProxyKennwort -x derProxy:derPortVomProxy -m 120 -u derUserBeimServer:dasPasswortBeimServer -d "httpPostFeld1=Inahlt&httpPostFeld2=inhalt&httpPostFeld3=inhalt&httpPostFeld4=Inhalt" -k urlDerHttpPostAction
Bei mir hat sich genau die umgekehrte Effekt eingestellt. Warum gibt es für die gleiche Sache wie proxy-authentification so viele verschiedene Prozesse.
Z.B. muss man bei httpClient scheinbar
client.getParams().setAuthenticationPreemptive(true); // WICHTIG!!!!
setzen.
Jetzt kommt das hier:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
Nur für die Komplettierung.
Wir hatten hier ja einige Threads, wo man mit Java (oder anderen Plattformen) Webseiten auslesen sollte.
Die SSL Geschichte on top war jetzt ein bischen nervig.
Es geht darum, dass der Client dem Server vertraut. Es geht nicht um Client Authentifizierung.
Eine einfache Sache, mag man denken.
In Java und in Browsern ist das so implementiert, dass Servern die einen public key haben, der mit einer CA signiert ist, die sich in einem gewissen Repository befindet, grundsätzlich vertraut wird.
Ansonsten setzt es eine
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found.
Standardmässig ist dieses Repository in Java dies in einer Datei cacerts.
Genauer:
jre\lib\security\cacerts
Das Format ist irgendwie binary.
Man kann sich den Inhalt aber Klartext ausgeben, wenn man diese Zeile im code setzt, bevor versucht wird irgendwelche SSL-Verbindungen zu öffnen:
System.setProperty("javax.net.debug", "ssl");
Es gibt dann noch diverse Tools im jsdk, mit dem man da neue CA-certs reinbringt. Leider sind das Kommandozeilentools, die ein bischen nervig sind. Über google findet man kleine, nicht so toll geschriebene Java Programme, die aber super funktionieren und bei der Bedienung dieser Kommando-Zeilen Tools helfen.
Z.B:
http://diakonia.org.za/webCDcreator/4pluginRSA/installCA.html
Viele CA-certs sind schon von Hause aus im cacerts-Repository. Das in Deutschland recht verbreitete TrustCenter leider nicht. Die Infos für CA in Browser bringen sind noch ganz ok. Die Infos für Leute, die die CA in Java cacerts (oder auf anderen Prog-Plattformen) bringen wollen, hingegen imnsho katastrophal.
So ungewöhnlich dürfte dieses Ansinnen nicht sein.
So eine Informationspolitik hat natürlich Folgen.
Z.B. schaltet der php-Beispielcode einer Deutschen Großbank SSL-Server-Authentifizierung der Einfachheit halber ganz aus >:( . Es ist an dieser Stelle vielleicht auch nicht so wichtig. Besonders toll finde ich das aber nicht. In einer besseren Welt sollten Banken grundsätzlich an der Einhaltung an Sicherheitsprozessen interessiert sein.
Ein tolles Buch für Java Security ist: Pankaj Kumar, J2EE Security.
Der Javacode ist dem Skript-Code von mir recht ähnlich, auch in .NET ist es fast identisch zu machen.
Ist mir jetzt bei Garry Devendorfs code auch aufgefallen.
http://blog.advisor.com/blog/garydev.nsf/d6plinks/GDEF-6LMV4M
Dieses
DominoWS.PreAuthenticate = True ' force credentials in first call
kam mir doch sehr bekannt vor.
Diese Libraries sind einfach sehr feingranulare und dünne wrapper um das http Protokoll. Durch Lesen der HTTP-spec wird man die Library besser verstehen. Und so umfangreich ist die nicht. Und man kann sich mit http-sniffern, interceptoren etc. Life anschauen, was wirklich zwischen Client und Server ausgetauscht wird.
Manchmal sind solche Libraries eng am technischen Objekt einfacher.
Z.B. haben wir uns geeinigt, dass ich Spring wrapper um die apache.commons.HttpClient benutze. Die haben das in spring integriert. Der code wird weniger und die Konfiguration wird konsistenter mit dem Rest-Projekt.
Nur fällt es mir in diesem Fall schwerer die Library on top zu verstehen als die low level (jakarta.commons.HttpClient). Obwohl Spring für mich heilig ist.
Es gibt eben keine Absolutheiten und es hängt sehr oft vom Einzelfall ab.
Axel