Proteggere le app Java Spring Boot con Microsoft Entra ID

Questo articolo illustra un'app Web Java Spring Boot che consente agli utenti di accedere nel tenant di Microsoft Entra ID usando la libreria client Microsoft Entra ID Spring Boot Starter client library for Java. Usa il protocollo OpenID Connect.

Il diagramma seguente illustra la topologia dell'app:

Diagramma che mostra la topologia dell'app.

L'app client usa la libreria client Microsoft Entra ID Spring Boot Starter per Java per consentire l'accesso a un utente e ottenere un token ID da Microsoft Entra ID. Il token ID dimostra che l'utente è autenticato con Microsoft Entra ID e consente all'utente di accedere alle route protette.

Prerequisiti

Consigli

  • Una certa familiarità con il Spring Framework.
  • Una certa familiarità con il terminale Linux/OSX.
  • jwt.ms per controllare i token.
  • Fiddler per monitorare l'attività di rete e risolvere i problemi.
  • Segui il blog di Microsoft Entra per rimanere up-to-date con gli ultimi sviluppi.

Configurare l'esempio

Le sezioni seguenti illustrano come configurare l'applicazione di esempio.

Clonare o scaricare il repository di esempio

Per clonare l'esempio, aprire una finestra Bash e usare il comando seguente:

git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 4-spring-web-app/1-Authentication/sign-in

In alternativa, passare al repository ms-identity-msal-java-samples, quindi scaricarlo come file .zip ed estrarlo sul disco rigido.

Importante

Per evitare limitazioni di lunghezza del percorso in Windows, è consigliabile clonare in una directory vicina alla radice dell'unità.

Registrare le applicazioni di esempio nel tenant Microsoft Entra ID

In questo esempio è presente un progetto. Le sezioni seguenti illustrano come registrare l'app usando il portale di Azure.

Scegliere il tenant microsoft Entra ID in cui si desidera creare le applicazioni

Per scegliere il tenant, seguire questa procedura:

  1. Accedere al portale di Azure.

  2. Se l'account è presente in più tenant di Microsoft Entra ID, selezionare il profilo nell'angolo del portale di Azure e quindi selezionare Cambia directory per modificare la sessione nel tenant di Microsoft Entra ID desiderato.

Registrare l'app (java-spring-webapp-auth)

Per registrare l'app, seguire questa procedura:

  1. Passare al portale di Azure e selezionare Microsoft Entra ID.

  2. Selezionare Registrazioni app nel riquadro di spostamento, quindi selezionare Nuova registrazione.

  3. Nella pagina Registra un'applicazione visualizzata immettere le informazioni di registrazione dell'applicazione seguenti:

    • Nella sezione Name, immetti un nome significativo per l'applicazione da mostrare agli utenti dell'app, ad esempio java-spring-webapp-auth.
    • In Tipi di account supportati selezionare Solo tenant singolo - TENANT_NAME (TENANT_NAME varia per tenant).
    • Nella sezione URI di reindirizzamento (facoltativo), seleziona Web nella casella combinata e inserisci il seguente URI di reindirizzamento: http://localhost:8080/login/oauth2/code/.
  4. Selezionare Registra per creare l'applicazione.

  5. Nella pagina di registrazione dell'app, trova e copia il valore ID applicazione (client) da utilizzare in seguito. Questo valore viene usato nel file o nei file di configurazione dell'app.

  6. Nella pagina di registrazione dell'app selezionare Certificati e segreti nel riquadro di spostamento per aprire la pagina in cui è possibile generare segreti e caricare i certificati.

  7. Nella sezione Segreti client seleziona Nuovo segreto client.

  8. Digitare una descrizione, ad esempio il segreto dell'app.

  9. Selezionare una delle durate disponibili: consigliata: 180 giorni (6 mesi),90 giorni (3 mesi),365 giorni (12 mesi),545 giorni (18 mesi) o 730 giorni (24 mesi).

  10. Selezionare Aggiungi. Viene visualizzato il valore generato.

  11. Copiare e salvare il valore generato da usare nei passaggi successivi. Questo valore è necessario per i file di configurazione del codice. Questo valore non viene visualizzato di nuovo e non è possibile recuperarlo con altri mezzi. Assicurarsi quindi di salvarlo dal portale di Azure prima di passare a qualsiasi altra schermata o riquadro.


Configurare l'app (java-spring-webapp-auth) per usare la registrazione dell'applicazione

Usare la procedura seguente per configurare l'app:

Nota

Nei passaggi seguenti, ClientID corrisponde a Application ID o AppId.

  1. Aprire il progetto nell'IDE.

  2. Apri il file src\main\resources\application.yml.

  3. Individua il segnaposto Enter_Your_Tenant_ID_Here e sostituisci il valore esistente con l'ID del tenant di Microsoft Entra.

  4. Trovare il segnaposto Enter_Your_Client_ID_Here e sostituire il valore esistente con l'ID applicazione dell'app java-spring-webapp-auth o clientId copiato dal portale di Azure.

  5. Individuare il segnaposto Enter_Your_Client_Secret_Here e sostituire il valore esistente con il valore salvato durante la creazione di java-spring-webapp-auth, copiato dal portale di Azure.

Esegui l'esempio

Le sezioni seguenti illustrano come distribuire l'esempio in App Contenitore di Azure.

Prerequisiti

Preparare il progetto Spring

Per preparare il progetto, seguire questa procedura:

  1. Usa il seguente comando Maven per compilare il progetto:

    mvn clean verify
    
  2. Eseguire il progetto di esempio in locale usando il comando seguente:

    mvn spring-boot:run
    

Configurazione

Per accedere ad Azure dall'interfaccia della riga di comando, eseguire il comando seguente e seguire le istruzioni per completare il processo di autenticazione.

az login

Per assicurarti di utilizzare la versione più recente della CLI, esegui il comando di aggiornamento.

az upgrade

Successivamente, installare o aggiornare l'estensione App contenitore di Azure per l'interfaccia a riga di comando.

Se si ricevono errori relativi a parametri mancanti quando si eseguono i comandi az containerapp in interfaccia della riga di comando di Azure, assicurarsi di avere installato la versione più recente dell'estensione App contenitore di Azure.

az extension add --name containerapp --upgrade

Nota

A partire da maggio 2024, le estensioni dell'interfaccia della riga di comando di Azure non abilitano più le funzionalità di anteprima per impostazione predefinita. Per accedere alle funzionalità in anteprima di Container Apps, installa l'estensione di Container Apps con --allow-preview true.

az extension add --name containerapp --upgrade --allow-preview true

Ora che l'estensione o il modulo corrente è installato, registrare i namespace Microsoft.App e Microsoft.OperationalInsights.

Nota

Le risorse di App contenitore di Azure sono state migrate dallo spazio dei nomi Microsoft.Web allo spazio dei nomi Microsoft.App. Per altre informazioni, vedere Migrazione dello spazio dei nomi da Microsoft.Web a Microsoft.App a marzo 2022.

az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights

Creare l'ambiente di App contenitore di Azure

Dopo aver completato la configurazione dell'interfaccia della riga di comando di Azure, è possibile definire le variabili di ambiente usate in questo articolo.

Definire le variabili seguenti nella shell Bash.

export RESOURCE_GROUP="ms-identity-containerapps"
export LOCATION="canadacentral"
export ENVIRONMENT="env-ms-identity-containerapps"
export API_NAME="ms-identity-api"
export JAR_FILE_PATH_AND_NAME="./target/ms-identity-spring-boot-webapp-0.0.1-SNAPSHOT.jar"

Crea un gruppo di risorse.

az group create  \
    --name $RESOURCE_GROUP \
    --location $LOCATION \

Creare un ambiente con un'area di lavoro Log Analytics generata automaticamente.

az containerapp env create \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION

Mostra il dominio predefinito dell'ambiente dell'app contenitore. Annotare questo dominio da usare nelle sezioni successive.

az containerapp env show \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --query properties.defaultDomain

Preparare l'app per la distribuzione

Quando distribuisci l'applicazione in App contenitore di Azure, l'URL di reindirizzamento cambia nell'URL di reindirizzamento dell'istanza distribuita dell'app in App contenitore di Azure. Utilizza i passaggi seguenti per modificare queste impostazioni nel file application.yml:

  1. Vai al file src\main\resources\application.yml della tua app e modifica il valore di post-logout-redirect-uri impostandolo sul nome di dominio della tua app distribuita, come mostrato nell'esempio seguente. Assicurati di sostituire <API_NAME> e <default-domain-of-container-app-environment> con i valori effettivi. Ad esempio, con il dominio predefinito per il tuo ambiente di Azure Container Apps del passaggio precedente e ms-identity-api come nome dell'app, useresti https://ms-identity-api.<default-domain> come valore di post-logout-redirect-uri.

    post-logout-redirect-uri: https://<API_NAME>.<default-domain-of-container-app-environment>
    
  2. Dopo aver salvato questo file, usare il comando seguente per ricompilare l'app:

    mvn clean package
    

Importante

Il file application.yml dell'applicazione contiene attualmente il valore del segreto client nel parametro client-secret. Non è consigliabile mantenere questo valore in questo file. Se si esegue il commit del file in un repository Git, potrebbe anche essere rischioso. Per l'approccio consigliato, vedere Gestire i segreti in App contenitore di Azure.

Aggiornare la registrazione dell'app Microsoft Entra ID

Poiché l'URI di reindirizzamento cambia nell'app distribuita in App Azure Container, è anche necessario modificare l'URI di reindirizzamento nella registrazione dell'app Microsoft Entra ID. Attenersi alla seguente procedura per apportare questa modifica:

  1. Passa alla pagina Registrazioni app della piattaforma di identità Microsoft per sviluppatori.

  2. Usa la casella di ricerca per cercare la registrazione dell’applicazione, ad esempio, java-servlet-webapp-authentication.

  3. Aprire la registrazione dell'app selezionandone il nome.

  4. Seleziona Autenticazione dal menu.

  5. Nella sezione Web - URI di reindirizzamento, seleziona Aggiungi URI.

  6. Inserisci l'URI dell'app, aggiungendo /login/oauth2/code/; ad esempio, https://<containerapp-name>.<default domain of container app environment>/login/oauth2/code/.

  7. Seleziona Salva.

Distribuire l'app

Distribuire il pacchetto JAR in App contenitore di Azure.

Nota

Se necessario, è possibile specificare la versione JDK nelle variabili di ambiente di compilazione Java. Per ulteriori informazioni, vedi Variabili di ambiente di compilazione per Java in App contenitore di Azure.

Ora è possibile distribuire il file WAR con il comando CLI az containerapp up.

az containerapp up \
    --name $API_NAME \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION \
    --environment $ENVIRONMENT \
    --artifact <JAR_FILE_PATH_AND_NAME> \
    --ingress external \
    --target-port 8080 \
    --query properties.configuration.ingress.fqdn

Nota

La versione predefinita di JDK è 17. Se devi modificare la versione del JDK per garantire la compatibilità con la tua applicazione, puoi usare l'argomento --build-env-vars BP_JVM_VERSION=<YOUR_JDK_VERSION> per regolare il numero di versione.

Per altre variabili di ambiente di compilazione, vedi Variabili di ambiente di compilazione per Java in App contenitore di Azure.

Convalidare l'app

In questo esempio, il comando containerapp up include l'argomento --query properties.configuration.ingress.fqdn, che restituisce il nome di dominio completo (FQDN), detto anche URL dell'app. Usare la procedura seguente per controllare i log dell'app per analizzare eventuali problemi di distribuzione:

  1. Accedi all'URL di output dell'applicazione dalla pagina Outputs della sezione Deployment.

  2. Nel riquadro di navigazione della pagina Overview dell'istanza di App contenitore di Azure, selezionare Logs per verificare i log dell'app.

Esaminare l'esempio

Per esplorare l'esempio, seguire questa procedura:

  1. Notare lo stato di accesso o di disconnessione visualizzato al centro dello schermo.
  2. Selezionare il pulsante sensibile al contesto nell'angolo. Questo pulsante riporta Accedi quando avvii l'app per la prima volta. In alternativa, selezionare dettagli del token. Poiché questa pagina è protetta e richiede l'autenticazione, si viene reindirizzati automaticamente alla pagina di accesso.
  3. Nella pagina successiva, segui le istruzioni e accedi con un account nel tenant di Microsoft Entra ID.
  4. Nella schermata di consenso notare gli ambiti richiesti.
  5. Al termine del flusso di accesso, si dovrebbe essere reindirizzati alla home page, che mostra lo stato di accesso o la pagina dei dettagli del token, a seconda del pulsante che ha attivato il flusso di accesso.
  6. Si noti che il pulsante sensibile al contesto ora indica Disconnetti e visualizza il nome utente.
  7. Se ti trovi nella home page, seleziona ID Token Details per visualizzare alcune delle attestazioni decodificate del token ID.
  8. Usare il pulsante nell'angolo per disconnettersi. La pagina di stato riflette il nuovo stato.

Informazioni sul codice

Questo esempio mostra come usare la libreria client per Java Microsoft Entra ID Spring Boot Starter per consentire agli utenti di accedere al tenant di Microsoft Entra ID. L'esempio usa anche gli starter Spring Oauth2 Client e Spring Web Boot. L'esempio usa attestazioni del token ID ottenuto da Microsoft Entra ID per visualizzare i dettagli dell'utente connesso.

Contenuto

La tabella seguente illustra il contenuto della cartella del progetto di esempio:

File/cartella Descrizione
pom.xml Dipendenze dell'applicazione.
src/main/resources/templates/ Modelli thymeleaf per l'interfaccia utente.
src/main/resources/application.yml Configurazione della libreria Boot Starter per l'applicazione e Microsoft Entra ID.
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ Questa directory contiene i principali punti di ingresso, controller e classi di configurazione dell'applicazione.
.../MsIdentitySpringBootWebappApplication.java Classe principale.
.../SampleController.java Controller con mappatura degli endpoint.
.../SecurityConfig.java Configurazione di sicurezza, ad esempio le route che richiedono l'autenticazione.
.../Utilities.java Classe di utilità, ad esempio per filtrare i claim del token ID.
CHANGELOG.md Elenco delle modifiche apportate all'esempio.
CONTRIBUTING.md Linee guida per contribuire all'esempio.
LICENZA La licenza dell'esempio.

Attestazioni contenute nel token ID

Per estrarre i dettagli del token, l'app utilizza gli oggetti AuthenticationPrincipal e OidcUser di Spring Security in un mapping di richiesta, come mostrato nell'esempio seguente. Vedi il Controller di esempio per i dettagli completi su come questa app utilizza i claims del token ID.

import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
//...
@GetMapping(path = "/some_path")
public String tokenDetails(@AuthenticationPrincipal OidcUser principal) {
    Map<String, Object> claims = principal.getIdToken().getClaims();
}

Per l'accesso, l'app effettua una richiesta all'endpoint di accesso di Microsoft Entra ID configurato automaticamente dalla libreria client Spring Boot Starter per Microsoft Entra ID per Java, come illustrato nell'esempio seguente:

<a class="btn btn-success" href="/oauth2/authorization/azure">Sign In</a>

Per disconnettersi, l'app effettua una richiesta POST all'endpoint logout, come mostrato nell'esempio seguente:

<form action="#" th:action="@{/logout}" method="post">
  <input class="btn btn-warning" type="submit" value="Sign Out" />
</form>

Elementi dell'interfaccia utente dipendenti dall'autenticazione

L'app ha una logica semplice nelle pagine del modello di interfaccia utente per determinare il contenuto da visualizzare in base all'autenticazione dell'utente, come illustrato nell'esempio seguente usando i tag Spring Security Thymeleaf:

<div sec:authorize="isAuthenticated()">
  this content only shows to authenticated users
</div>
<div sec:authorize="isAnonymous()">
  this content only shows to not-authenticated users
</div>

Proteggere i percorsi con AADWebSecurityConfigurerAdapter

Per impostazione predefinita, l'app protegge la pagina ID Token Details in modo che solo gli utenti che hanno effettuato l'accesso possano accedervi. L'app configura questi percorsi utilizzando la proprietà app.protect.authenticated del file application.yml. Per configurare i requisiti specifici dell'app, applica il metodo AadWebApplicationHttpSecurityConfigurer#aadWebApplication all'istanza HttpSecurity. Per un esempio, vedi la classe SecurityConfig di questa app, mostrata nel codice seguente:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig  {
    
    @Value("${app.protect.authenticated}")
    private String[] allowedOrigins;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
            .and()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(allowedOrigins).authenticated()
                .anyRequest().permitAll()
                );
        // @formatter:on
        return http.build();
    }

    @Bean
    @RequestScope
    public ServletUriComponentsBuilder urlBuilder() {
        return ServletUriComponentsBuilder.fromCurrentRequest();
    }    
}

Ulteriori informazioni

Per altre informazioni su come funzionano i protocolli OAuth 2.0 in questo scenario e in altri scenari, vedere Scenari di autenticazione per Microsoft Entra ID.