Come abilitare HTTPS in un’applicazione Java Spring Boot su WINDOW
La configurazione di HTTPS per Spring Boot richiede due passaggi: ottenere un certificato SSL e configurare SSL in Spring Boot. Sia che tu stia per generare un certificato autofirmato o che ne abbia già ottenuto uno da una CA, ti mostrerò come abilitare HTTPS in un’applicazione Spring Boot.
La configurazione di HTTPS per Spring Boot richiede due passaggi:
- Ottenere un certificato SSL;
- Configurazione di SSL in Spring Boot.
Possiamo generare noi stessi un certificato SSL (certificato autofirmato). Il suo utilizzo è destinato esclusivamente a scopi di sviluppo e test. In produzione, dovremmo utilizzare un certificato emesso da un’autorità di certificazione (CA) affidabile.
In entrambi i casi, vedremo come abilitare HTTPS in un’applicazione Spring Boot.
introduzione
In questo tutorial:
- Ottieni un certificato SSL
- Genera un certificato SSL autofirmato
- Utilizza un certificato SSL esistente
- Abilita HTTPS in Spring Boot
- Reindirizzare le richieste HTTP a HTTPS
- Distribuire il certificato SSL ai client.
Se non disponi già di un certificato, segui il passaggio 1a. Se hai già un certificato SSL, puoi seguire il passaggio 1b.
In questo tutorial utilizzerò le tecnologie e gli strumenti seguenti:
- Java8+
- Stivale Boot 2.5+
- keytool
Keytool è un’utilità di gestione dei certificati fornita insieme al JDK, quindi se hai installato il JDK, dovresti già avere keytool disponibile. Per verificarlo, prova a eseguire il comando keytool --help
dal prompt del Terminale. Tieni presente che se utilizzi Windows, potrebbe essere necessario avviarlo dalla cartella \bin . Per maggiori informazioni su questa utility potete leggere la documentazione ufficiale .
1)Acquista un certificato
La soluzione migliore a mio parere è quello di richiedere un certificato SSL ad un’ Autority ,io ho usato il servizio zerossl , assicurarsi quindi di ricevere il certificato con estensione crt e la chiave privata. Ricordati che il certificato deve essere associato ad un dominio esistente.
Una volta scaricato il tutto clicca sul file .crt si aprirà la seguente popup:
Successivamente cliccare sul pulsante installa certificato–>Local Machine ed inserirlo sotto la voce “Trusted Root Certification Authorities”
2)Converti il certificato nei formati PKCS12 oppure JKS
Se tutto è andato bene dovresti essere in possesso dei seguenti file :
ca_bundle.crt
private.key
certificate.crt
Converti il certificato nel formato PKCS12
openssl pkcs12 -export -in certificate.crt -inkey private.key -name xxxxxxxxxx -out xxxxxxxxxx.p12
Questo genererà un file .p12
Importa il file PKCS12 nel keystore JKS
keytool -importkeystore -deststorepass <password> -destkeystore xxxxxxxxxx.jks -srckeystore xxxxxxxxxxx.p12 -srcstoretype PKCS12
Verrà creato un file con estensione .jks.
Importa il certificato del bundle CA nell’archivio chiavi JKS
keytool -import -alias xxxxxxxxxx -trustcacerts -file ca_bundle.crt -keystore xxxxxxxxxx.jks
Verificare il contenuto dell’archivio chiavi
Per verificare il contenuto del keystore seguendo il formato JKS , possiamo utilizzare nuovamente keytool:
keytool -list -v -keystore xxxxxxxxxx.jks
Per testare il contenuto di un keystore seguendo il formato PKCS12 :
keytool -list -v -keystore xxxxxxxxxx.p12
1b. Utilizza un certificato SSL esistente
Nel caso in cui disponiamo già di un certificato SSL, ad esempio uno emesso da Let’s Encrypt , possiamo importarlo in un keystore e utilizzarlo per abilitare HTTPS in un’applicazione Spring Boot.
Possiamo utilizzare keytool per importare il nostro certificato in un nuovo archivio di chiavi.
keytool -import -alias springboot -file myCertificate.crt -keystore springboot.p12 -storepass password
Per ottenere maggiori informazioni sul keystore e sul suo formato, fare riferimento alla sezione precedente.
2. Abilita HTTPS in Spring Boot
Se il nostro archivio chiavi contiene un certificato autofirmato o uno emesso da un’autorità di certificazione attendibile, ora possiamo configurare Spring Boot per accettare richieste su HTTPS anziché HTTP utilizzando quel certificato.
La prima cosa da fare è posizionare il file keystore all’interno del progetto Spring Boot. A scopo di test, vogliamo inserirlo nella cartella delle risorse o nella cartella principale. In produzione probabilmente vorrai utilizzare una soluzione di gestione dei segreti per gestire il keystore.
Quindi, configuriamo il server per utilizzare il nostro nuovissimo archivio chiavi e abilitare HTTPS.
Abilita HTTPS in Spring Boot
Per abilitare HTTPS per la nostra applicazione Spring Boot, apriamo il nostro file application.properties e definiamo le seguenti proprietà:
server.ssl.key-store= xxxxxxxx.p12
server.ssl.key-store-password= changeme
server.ssl.key-store-type= pkcs12
server.ssl.key-alias= xxxxxxxxxx
server.ssl.key-password= changeme
server.ssl.port= 8443
server.ssl.enabled=true
Configurazione di SSL in Spring Boot
Diamo uno sguardo più da vicino alla configurazione SSL che abbiamo appena definito nelle proprietà dell’applicazione Spring Boot.
server.port
: la porta su cui è in ascolto il server. Abbiamo utilizzato8443
invece la8080
porta predefinita.server.ssl.key-store
: il percorso dell’archivio chiavi che contiene il certificato SSL. Nel nostro esempio, vogliamo che Spring Boot lo cerchi nel classpath.server.ssl.key-store-password
: la password utilizzata per accedere al key store.server.ssl.key-store-type
: il tipo di archivio chiavi (JKS o PKCS12).server.ssl.key-alias
: l’alias che identifica la chiave nel key store.server.ssl.key-password
: la password utilizzata per accedere alla chiave nel key store.
Reindirizzamento a HTTPS con Spring Security
Quando utilizziamo Spring Security, possiamo configurarlo per bloccare automaticamente qualsiasi richiesta proveniente da un canale HTTP non sicuro e reindirizzarla su HTTPS.
Creiamo una classe SecurityConfig per raccogliere le politiche di sicurezza e configurare l’applicazione per richiedere un canale sicuro per tutte le richieste. Possiamo anche autorizzare temporaneamente tutte le richieste in modo da poterci concentrare sul test del comportamento HTTPS piuttosto che sulla strategia di autenticazione dell’utente.
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.requiresChannel(channel ->
channel.anyRequest().requiresSecure())
.authorizeRequests(authorize ->
authorize.anyRequest().permitAll())
.build();
}
}
Per ulteriori informazioni su come configurare SSL in Spring Boot, puoi dare un’occhiata alla Guida di riferimento . Se vuoi scoprire quali proprietà sono disponibili per configurare SSL, puoi fare riferimento alla definizione nel code-base.
Congratulazioni! Hai abilitato con successo HTTPS nella tua applicazione Spring Boot! Provalo: esegui l’applicazione, apri il browser, visita https://localhost:8443 e controlla se tutto funziona come dovrebbe.
Se utilizzi un certificato autofirmato, probabilmente riceverai un avviso di sicurezza dal browser e dovrai comunque autorizzarlo ad aprire la pagina web.
3. Connettori multipli per HTTP e HTTPS
Spring consente di definire un solo connettore di rete in application.properties (o application.yml ). Lo abbiamo utilizzato per HTTPS e ci siamo affidati a Spring Security per reindirizzare tutto il traffico HTTP su HTTPS.
Cosa succede se abbiamo bisogno sia dei connettori HTTP che HTTPS in Tomcat e reindirizzamo tutte le richieste al secondo? Possiamo mantenere la configurazione HTTPS nel file application.yml e impostare il connettore HTTP a livello di codice.
@Configuration
public class ServerConfig {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
var securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
var collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(getHttpConnector());
return tomcat;
}
private Connector getHttpConnector() {
var connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
4. Ci siamo quasi
Quando utilizzi un certificato SSL autofirmato, il nostro browser non si fiderà della nostra applicazione e avviserà l’utente che non è sicura. E sarà lo stesso con qualsiasi altro cliente.
È possibile fare in modo che un cliente fidi della nostra applicazione fornendogli il nostro certificato.
Estrai un certificato SSL da un archivio di chiavi
Abbiamo archiviato il nostro certificato all’interno di un archivio di chiavi, quindi dobbiamo estrarlo. Ancora una volta, keytool ci supporta molto bene:
keytool -export -keystore springboot.p12 -alias springboot -file myCertificate.crt
Il keystore può essere in formato JKS o PKCS12. Durante l’esecuzione di questo comando, keytool ci chiederà la password del keystore che abbiamo impostato all’inizio di questo tutorial (la password estremamente sicura ).
Ora possiamo importare il nostro certificato nel nostro client. Successivamente vedremo come importare il certificato nella JRE nel caso in cui ne avessimo bisogno per fidarci della nostra applicazione.
Importa un certificato SSL all’interno del keystore JRE
Per fare in modo che JRE si fidi del nostro certificato, dobbiamo importarlo all’interno di cacerts : il trust store JRE incaricato di conservare tutti i certificati di cui ci si può fidare.
Innanzitutto, dobbiamo conoscere il percorso verso la nostra casa JDK. Un modo rapido per trovarlo, se utilizziamo Eclipse o STS come IDE, è andare su Preferenze > Java > JRE installati . Se utilizzi IntelliJ IDEA, possiamo accedere a queste informazioni andando su Struttura del progetto > SDK e osservando il valore del campo del percorso home JDK .
Su macOS, potrebbe essere qualcosa come /Library/Java/JavaVirtualMachines/adoptopenjdk-16.jdk/Contents/Home. Di seguito faremo riferimento a questa posizione utilizzando il segnaposto $JDK_HOME
.
Quindi, dal prompt del nostro Terminale, inseriamo il seguente comando (potremmo doverlo eseguire con privilegi di amministratore prefissandolo con sudo
):
keytool -importcert -file myCertificate.crt -alias springboot -keystore $JDK_HOME/jre/lib/security/cacerts
Ci verrà chiesto di inserire la password del keystore JRE. Se non l’hai mai cambiato, dovrebbe essere quello predefinito: changeit o changeme , a seconda del sistema operativo. Infine, keytool ti chiederà se vuoi fidarti di questo certificato: diciamo sì .
Se tutto è andato bene, vedremmo il messaggio Certificate wasAdd to keystore . Grande!