Introduzione
Negli articoli dedicati all'integrazione di applicazioni Enterprise (vedere [MOKAINT]) si era visto come permettere la comunicazione con EJB sfruttando l'interoperabilità del protocollo IIOP. In [MOKASSLIOP] si è parlato di come esporre (e accedere), in modo sicuro, oggetti remoti attraverso il protocollo IIOP over SSL.
In questo articolo ci "spostiamo a valle" del layer di business e parleremo delle principali tipologie di accesso sicuro al layer di presentation.
Si mostrerà come accedere via HTTP (via proxy e mediante Basic Authentication) e HTTPS (Basic Authenticational e mediante certificati) in modo programmatico al layer di presentation, usando le classi HTTP Client di Jakarta [JAKARTA_HTTPCLIENT] e il servlet container Tomcat [TOMCAT].
Le API HttpClient di Jakarta
Per invocare un URL mediante le API HttpClient di Jakarta basta effettuare i seguenti passi. Creare un'istanza della classe HttpClient
Creare un'istanza del metodo che si vuole invocare: GetMethod per invocazioni HTTP GET
e PostMethod per invocazioni HTTP POST
## Invocare il metodo executeMethod() passando come argomento l'HttpMethod:
Impostare gli eventuali parametri d'input
## Leggere e gestire la risposta
byte[] responseBody = httpget.getResponseBody();
String response=new String(responseBody);
System.out.println("Risposta:" + response);
httpMethod.releaseConnection();
GetMethod httpget = null;
try {
// Creazione HttpClient HttpClient httpclient = new HttpClient();
// Creazione GET method httpget = new GetMethod("http://www.MokaByte.it");
// invocazione int statusCode = httpclient.executeMethod(httpget);
// lettura della risposta byte[] responseBody = httpget.getResponseBody();
String response=new String(responseBody);
System.out.println(method + " Response ["+ response+"]...");
} catch (Exception e) {
e.printStackTrace();
}
finally{
httpget.releaseConnection();
}
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler( 2 , false));
HttpClient httpclient = new HttpClient();
// Proxy Authentication (senza questa istruzione avrei un HTTP 401)
httpclient.getHostConfiguration().setProxy("
<<indirizzo IP del Proxy>>
",
<<Porta TCP del Proxy>>
);
httpclient.getHostConfiguration().setProxy("<<indirizzo IP del Proxy>>", <<Porta TCP del Proxy>>);
httpclient.getState().setProxyCredentials( AuthScope.ANY,
new UsernamePasswordCredentials("
<<USERNAME>>
", "
<<PASSWORD>>
"));
new UsernamePasswordCredentials("<<USERNAME>>", "<<PASSWORD>>"));
<auth-method>BASIC</auth-method> Le risorse da proteggere devono invece essere specificate mediante i tag <security-constraint> e <login-config>. Ad esempio, per mettere sotto protezione <url-pattern>/mine/*</url-pattern>
<security-constraint> <web-resource-collection> <web-resource-name> Entire Application </web-resource-name> <url-pattern>/mine/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>
<<ROLENAME>>
</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>BASIC</auth-method> <realm-name>My Rolename-only Area</realm-name> </login-config>
<security-constraint> <web-resource-collection> <web-resource-name> Entire Application </web-resource-name> <url-pattern>/mine/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name><<ROLENAME>></role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>BASIC</auth-method> <realm-name>My Rolename-only Area</realm-name> </login-config>
<<CATALINA_BASE>>/conf/tomcat-users.xml aggiungendo le utenze ed i relativi ruoli mediante i tag <role> and <user>. <?xml version='1.0' encoding='utf-8'?> <tomcat-users> . . . <role rolename="<<ROLENAME>>"/> . . . <user username="<<USERNAME>>" password="<<PASSWORD>>" roles="<<ROLENAME>>"/> </tomcat-users>
http://
<<servername>>
:8080/kokhttps/mine/my_private_page.jsp
http://<<servername>>:8080/kokhttps/mine/myprivatepage.jsp
httpclient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(<<USERNAME>>, <<PASSWORD>>));
Il keytool memorizza le chiavi e i certificati in un keystore, che generalmente è un file con estensione .jks, proteggendo le chiavi private con password. Un file di chiavi contenente solo certificati (e non anche la chiave privata, come avviene per il keystore) viene invece chiamato trustStore. keytool -genkey -alias mokaserveralias -keystore mokaserverkeystore.ks –dname "CN=Amedeo, OU=Redazione, O=MokaByte, L=BO, S=IT, C=IT" -storepass tds1977 C:\MokaByte\samplehttps\cert>D:\installed\jdk1.5.006\bin\keytool -genkey -alias mokaserveralias -keystore mokaserverkeystore.ks -dname "CN=Amedeo, OU=Redazione, O=MokaByte, L=BO, S=IT, C=IT" -storepass tds1977 Immettere la password della chiave per <mokaserveralias> (INVIO se corrisponde alla password del keystore): [INVIO] Per importare il certificato precedentemente esportato in un trustStore sul client è possibile utilizzare l'utility di import, specificando il .cer che si vuole importare e il nome del trustStore che si vuole creare. keytool -import -keystore mokaclienttruststore.ks -alias mokaserveralias -file mokaserver.cer -storepass tds1982 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" keystoreFile ="J:/Programmi/tomcat-6.0.13/conf/tempArti/mokaserverkeystore.ks" keystorePass="tds1977" sslProtocol="TLS" />
A questo punto è possibile lanciare Tomcat e provare la connessione HTTPS sull'opportuna porta configurata. In questo modo se si richiede di accedere all'URL https://
<<servername>>
:8443/kokhttps/mine/my_private_page.jsp compare dapprima la popup del certificato e successivamente la popup di autenticazione.
A questo punto è possibile lanciare Tomcat e provare la connessione HTTPS sull'opportuna porta configurata. In questo modo se si richiede di accedere all'URL https://<<servername>>:8443/kokhttps/mine/myprivatepage.jsp compare dapprima la popup del certificato e successivamente la popup di autenticazione. sysprops.put("java.protocol.handler.pkgs","javax.net.ssl.internal.www.protocol");
sysprops.put("javax.net.debug", "ssl,handshake,data,trustmanager");
sysprops.put("javax.net.ssl.trustStore",
<<TRUSTSTORE FILE>>
);
sysprops.put("javax.net.ssl.trustStore", <<TRUSTSTORE FILE>>);
sysprops.put("javax.net.ssl.trustStorePassword",
<<STOREPASS>>
);
sysprops.put("javax.net.ssl.trustStorePassword", <<STOREPASS>>);
sysprops.put("javax.net.ssl.trustStoreType", "JKS");
HttpClient httpclient = new HttpClient();
httpget = new GetMethod("https://localhost:8443/kokhttps/mine/myprivatepage.jsp); httpclient.getState().setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(
<<USERNAME>>
,
<<PASSWORD>>
));
new UsernamePasswordCredentials(<<USERNAME>>, <<PASSWORD>>)); int statusCode = httpclient.executeMethod(httpget);
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="true" keystoreFile="J:/Programmi/tomcat-6.0.13/conf/tempArti/mokaserverkeystore.ks" keystorePass="tds1977" truststoreFile="J:/Programmi/tomcat-6.0.13/conf/tempArti/mokaservertruststore.ks" truststorePass="sos888" sslProtocol="TLS" />
sysprops.put("java.protocol.handler.pkgs","javax.net.ssl.internal.www.protocol"); sysprops.put("javax.net.debug", "ssl,handshake,data,trustmanager");
sysprops.setProperty("javax.net.debug", "true");
sysprops.put("javax.net.ssl.trustStore",
<<TRUSTSTORE FILE>>
));
sysprops.put("javax.net.ssl.trustStore",<<TRUSTSTORE FILE>>));
sysprops.put("javax.net.ssl.trustStorePassword",
<<STOREPASS>>
);
sysprops.put("javax.net.ssl.trustStorePassword", <<STOREPASS>>);
sysprops.put("javax.net.ssl.trustStoreType", "JKS"); HttpClient httpclient = new HttpClient();
// Execute the method. int statusCode = httpclient.executeMethod(httpget);
