Nel precedente articolo abbiamo configurato il server Wildfly per consentire la mutua autenticazione SSL client-server. In questo articolo realizziamo una semplice applicazione Web in stile "Hello World" che consenta di verificarne il corretto funzionamento.
Configurazione del client
Per poter contattare con successo l'applicazione Web dimostrativa, è necessario preliminarmente aggiungere nel browser il certificato del client creato nel precedente articolo. Se si utilizza Chrome, aprire le impostazioni del browser, posizionarsi in "Privacy e Sicurezza", espandere "Altro", selezionare "Gestisci certificati" e importare il file p12 relativo al certificato del client.
Nel caso di altri browser la procedura è simile, occorre sempre entrare nella gestione dei certificati e importare il file.
Configurazione della Web Application
L'applicazione Web Java EE di test fa uso delle servlet API 3.0 e richiede la seguente configurazione preliminare per il file web.xml
:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/hello/*</url-pattern> </servlet-mapping> </web-app>
Le linee inserite all'interno del file web.xml
consentono l'attivazione del funzionamento dei servizi REST, il server avrà la responsabilità di aggiungere automaticamente la servlet indicata.
Per consentire il rilevamento automatico di tutti i servizi REST dichiarati, è necessario aggiungere all'interno della directory WEB-INF
dell'applicazione un file XML denominato beans
ed avente il seguente contenuto:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all"> </beans>
Il codice Java
L'applicativo consiste essenzialmente in una servlet e in una classe per il servizio REST. Invocando la servlet, il servizio REST viene richiamato ed il suo contenuto inserito automaticamente nel codice HTML costruito dinamicamente. La prima classe che illustriamo è il servizio REST:
public class RestService {
public String restMessage(Stringname) {
return "Ciao, la mutua autenticazione SSL è correttamente configurata ed il certificato è valido!";
}
}
Si tratta di una classe molto semplice a cui viene delegato soltanto il compito di stampare un messaggio. Vediamo adesso la classe che realizza la servlet di entrata dell'applicazione. Il codice, decisamente più ricco, è il seguente:
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Base64;
@SuppressWarnings("serial")
@WebServlet("/RESTService")
public class RESTServlet extends HttpServlet {
@Inject
private RESTService restService;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<html><head><title>helloworld</title></head><body>");
writer.println("<h2>" + restService.restMessage() + "</h2>");
writer.println("<h5>Certificato client in formato Pem: " + getPemCertificate(extractCertificate(req)) + "</h5>");
writer.println("</body></html>");
writer.close();
}
protected X509Certificate extractCertificate(HttpServletRequest req) {
X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
if (null != certs && certs.length > 0) {
return certs[0];
}
throw new RuntimeException("Certificato client X.509 non presente nella richiesta");
}
protected String getPemCertificate(X509Certificate certificate) throws ServletException {
if (certificate != null) {
try {
return Base64.getEncoder().encodeToString(certificate.getEncoded());
} catch (CertificateEncodingException e) {
throw new ServletException(e);
}
}
return null;
}
}
La servlet fa poche cose ma molto interessanti; invoca il servizio REST per restituire un messaggio all'utente, mostra il formato PEM del certificato stesso utilizzando, per la sua estrazione,
le API Java per la sicurezza.
Una volta creato lo scheletro di una Web application JEE che contenga le classi e file XML illustrati, è sufficiente deployare il relativo file WAR all'interno del percorso di deploy JBOSS_HOME\standalone\deployments
di JBoss Wildfly ed aprire l'applicazione da Browser.