Abilitare l'accesso per le app Java Tomcat usando MSAL4J con Azure Active Directory B2C
Questo articolo illustra un'applicazione Java Tomcat che autentica gli utenti con Azure Active Directory B2C (Azure AD B2C) usando Microsoft Authentication Library per Java (MSAL4J).
Il diagramma seguente illustra la topologia dell'app:
L'app usa MSAL4J per accedere agli utenti e ottenere un token ID da Azure AD B2C. Il token ID dimostra che l'utente viene autenticato in un tenant di Azure AD B2C.
Prerequisiti
- JDK versione 8 o successiva
- Maven 3
- Un tenant di Azure AD B2C. Per altre informazioni, vedere Esercitazione: Creare un tenant di Azure Active Directory B2C
- Un account utente nel tenant di Azure AD B2C.
Consigli
- Familiarità con Java /Jakarta Servlets.
- Una certa familiarità con il terminale Linux/OSX.
- jwt.ms per controllare i token.
- Fiddler per monitorare l'attività di rete e la risoluzione dei problemi.
- Segui il blog di Microsoft Entra ID per rimanere aggiornato 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 3-java-servlet-web-app/1-Authentication/sign-in-b2c
In alternativa, passare al repository ms-identity-msal-java-samples , quindi scaricarlo come file .zip ed estrarlo nel disco rigido.
Importante
Per evitare limitazioni di lunghezza del percorso di file in Windows, clonare o estrarre il repository in una directory vicino alla radice del disco rigido.
Registrare l'applicazione di esempio con il tenant di Azure AD B2C
L'esempio viene fornito con un'applicazione preregistrata a scopo di test. Se si vuole usare un tenant e un'applicazione Azure AD B2C personalizzati, seguire la procedura descritta nelle sezioni seguenti per registrare e configurare l'applicazione nel portale di Azure. In caso contrario, continuare con i passaggi per Eseguire l'esempio.
Scegliere il tenant di Azure AD B2C in cui si vogliono creare le applicazioni
Per scegliere il tenant, seguire questa procedura:
Accedere al portale di Azure.
Se l'account è presente in più tenant di Azure AD B2C, selezionare il profilo nell'angolo del portale di Azure e quindi selezionare Cambia directory per modificare la sessione nel tenant di Azure AD B2C desiderato.
Creare flussi utente e criteri personalizzati
Per creare flussi utente comuni come l'iscrizione, l'accesso, la modifica del profilo e la reimpostazione della password, vedere Esercitazione: Creare flussi utente in Azure Active Directory B2C.
È consigliabile prendere in considerazione anche la creazione di criteri personalizzati in Azure Active Directory B2C , ma questo non rientra nell'ambito di questa esercitazione.
Aggiungere provider di identità esterni
Vedere Esercitazione: Aggiungere provider di identità alle applicazioni in Azure Active Directory B2C.
Registrare l'app (ms-identity-b2c-java-servlet-webapp-authentication)
Per registrare l'app, seguire questa procedura:
Passare al portale di Azure e selezionare Azure AD B2C.
Selezionare Registrazioni app nel riquadro di spostamento e quindi selezionare Nuova registrazione.
Nella pagina Registra un'applicazione visualizzata immettere le informazioni di registrazione dell'applicazione seguenti:
- Nella sezione Nome immettere un nome di applicazione significativo da visualizzare agli utenti dell'app,
ms-identity-b2c-java-servlet-webapp-authentication
ad esempio . - In Tipi di account supportati selezionare Account in qualsiasi directory organizzativa e account Microsoft personali (ad esempio Skype, Xbox, Outlook.com).
- Nella sezione URI di reindirizzamento (facoltativo) selezionare Web nella casella combinata e immettere l'URI di reindirizzamento seguente:
http://localhost:8080/ms-identity-b2c-java-servlet-webapp-authentication/auth_redirect
.
- Nella sezione Nome immettere un nome di applicazione significativo da visualizzare agli utenti dell'app,
Selezionare Registra per creare l'applicazione.
Nella pagina di registrazione dell'app trovare e copiare il valore ID applicazione (client) da usare in un secondo momento. Questo valore viene usato nel file o nei file di configurazione dell'app.
Seleziona Salva per salvare le modifiche.
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.
Nella sezione Segreti client seleziona Nuovo segreto client.
Digitare una descrizione, ad esempio il segreto dell'app.
Selezionare una delle durate disponibili: in 1 anno, in 2 anni o Mai scadute.
Selezionare Aggiungi. Viene visualizzato il valore generato.
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 (ms-identity-b2c-java-servlet-webapp-authentication) per l'uso della registrazione dell'app
Usare la procedura seguente per configurare l'app:
Nota
Nei passaggi seguenti è ClientID
uguale Application ID
a o AppId
.
Aprire il progetto nell'IDE.
Aprire il file ./src/main/resources/authentication.properties .
Trovare la
aad.clientId
proprietà e sostituire il valore esistente con l'ID applicazione oclientId
dell'applicazionems-identity-b2c-java-servlet-webapp-authentication
dal portale di Azure.Trovare la
aad.secret
proprietà e sostituire il valore esistente con il valore salvato durante la creazione dell'applicazionems-identity-b2c-java-servlet-webapp-authentication
dal portale di Azure.Trovare la
aad.scopes
proprietà e sostituire il clientid applicazione esistente con il valore inseritoaad.clientId
nel passaggio 1 di questa sezione.Trovare la
aad.authority
proprietà e sostituire la prima istanza difabrikamb2c
con il nome del tenant di Azure AD B2C in cui è stata creata l'applicazionems-identity-b2c-java-servlet-webapp-authentication
nel portale di Azure.Trovare la
aad.authority
proprietà e sostituire la seconda istanza difabrikamb2c
con il nome del tenant di Azure AD B2C in cui è stata creata l'applicazionems-identity-b2c-java-servlet-webapp-authentication
nel portale di Azure.Trovare la
aad.signInPolicy
proprietà e sostituirla con il nome del criterio di iscrizione/accesso del flusso utente creato nel tenant di Azure AD B2C in cui è stata creata l'applicazionems-identity-b2c-java-servlet-webapp-authentication
nel portale di Azure.Trovare la
aad.passwordResetPolicy
proprietà e sostituirla con il nome dei criteri del flusso utente di reimpostazione della password creati nel tenant di Azure AD B2C in cui è stata creata l'applicazionems-identity-b2c-java-servlet-webapp-authentication
nel portale di Azure.Trovare la
aad.editProfilePolicy
proprietà e sostituirla con il nome del criterio di modifica del flusso utente del profilo creato nel tenant di Azure AD B2C in cui è stata creata l'applicazionems-identity-b2c-java-servlet-webapp-authentication
nel portale di Azure.
Compilare l'esempio
Per compilare l'esempio usando Maven, passare alla directory contenente il file pom.xml per l'esempio e quindi eseguire il comando seguente:
mvn clean package
Questo comando genera un file con estensione war che è possibile eseguire in vari server applicazioni.
Eseguire l'esempio
Le sezioni seguenti illustrano come distribuire l'esempio in app Azure Servizio.
Prerequisiti
Plug-in Maven per app del servizio app Azure
Se Maven non è lo strumento di sviluppo preferito, vedere le esercitazioni simili seguenti che usano altri strumenti:
Configurare il plug-in Maven
Quando si esegue la distribuzione in app Azure Servizio, la distribuzione usa automaticamente le credenziali di Azure dall'interfaccia della riga di comando di Azure. Se l'interfaccia della riga di comando di Azure non è installata in locale, il plug-in Maven esegue l'autenticazione con OAuth o con l'accesso del dispositivo. Per altre informazioni, vedere Autenticazione con i plug-in Maven.
Per configurare il plug-in, seguire questa procedura:
Eseguire il comando seguente per configurare la distribuzione. Questo comando consente di configurare il sistema operativo del servizio app Azure, la versione Java e la versione di Tomcat.
mvn com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
Per Crea nuova configurazione di esecuzione, premere Y, quindi premere INVIO.
Per Definisci valore per il sistema operativo, premere 1 per Windows o 2 per Linux, quindi premere INVIO.
Per Definisci valore per javaVersion, premere 2 per Java 11 e quindi premere INVIO.
Per Definisci valore per webContainer, premere 4 per Tomcat 9.0, quindi premere INVIO.
Per Definisci valore per pricingTier, premere INVIO per selezionare il livello P1v2 predefinito.
Per Conferma premere Y, quindi premere INVIO.
L'esempio seguente mostra l'output del processo di distribuzione:
Please confirm webapp properties
AppName : msal4j-servlet-auth-1707209552268
ResourceGroup : msal4j-servlet-auth-1707209552268-rg
Region : centralus
PricingTier : P1v2
OS : Linux
Java Version: Java 11
Web server stack: Tomcat 9.0
Deploy to slot : false
Confirm (Y/N) [Y]: [INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 37.112 s
[INFO] Finished at: 2024-02-06T08:53:02Z
[INFO] ------------------------------------------------------------------------
Dopo aver confermato le scelte, il plug-in aggiunge l'elemento e le impostazioni del plug-in necessari al file di pom.xml del progetto per configurare l'app per l'esecuzione in app Azure Servizio.
La parte pertinente del file pom.xml dovrebbe essere simile all'esempio seguente:
<build>
<plugins>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>>azure-webapp-maven-plugin</artifactId>
<version>x.xx.x</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<resourceGroup>your-resourcegroup-name</resourceGroup>
<appName>your-app-name</appName>
...
</configuration>
</plugin>
</plugins>
</build>
È possibile modificare le configurazioni per servizio app direttamente nel pom.xml. Alcune configurazioni comuni sono elencate nella tabella seguente:
Proprietà | Richiesto | Descrizione |
---|---|---|
subscriptionId |
false | ID della sottoscrizione. |
resourceGroup |
true | Gruppo di risorse di Azure per l'app. |
appName |
true | Nome dell'app. |
region |
false | Area in cui ospitare l'app. Il valore predefinito è centralus . Per le aree valide, vedere Aree supportate. |
pricingTier |
false | Piano tariffario per l'app. Il valore predefinito è P1v2 per un carico di lavoro di produzione. Il valore minimo consigliato per lo sviluppo e il test Java è B2 . Per altre informazioni, vedere Prezzi di servizio app. |
runtime |
false | Configurazione dell'ambiente di runtime. Per altre informazioni, vedere Dettagli della configurazione. |
deployment |
false | Configurazione della distribuzione. Per altre informazioni, vedere Dettagli della configurazione. |
Per l'elenco completo delle configurazioni, vedere la documentazione di riferimento sul plug-in. Tutti i plug-in Azure Maven condividono un set comune di configurazioni. Per queste configurazioni, vedere Configurazioni comuni. Per le configurazioni specifiche del servizio app Azure, vedere App di Azure: Dettagli configurazione.
Assicurarsi di salvare i appName
valori e resourceGroup
per usarli in un secondo momento.
Preparare l'app per la distribuzione
Quando si distribuisce l'applicazione in servizio app, l'URL di reindirizzamento viene modificato nell'URL di reindirizzamento dell'istanza dell'app distribuita. Usare la procedura seguente per modificare queste impostazioni nel file delle proprietà:
Passare al file authentication.properties dell'app e modificare il valore di
app.homePage
in base al nome di dominio dell'app distribuita, come illustrato nell'esempio seguente. Ad esempio, se si sceglieexample-domain
per il nome dell'app nel passaggio precedente, è ora necessario usarehttps://example-domain.azurewebsites.net
per ilapp.homePage
valore . Assicurarsi di aver modificato anche il protocollo dahttp
ahttps
.# app.homePage is by default set to dev server address and app context path on the server # for apps deployed to azure, use https://your-sub-domain.azurewebsites.net app.homePage=https://<your-app-name>.azurewebsites.net
Dopo aver salvato questo file, usare il comando seguente per ricompilare l'app:
mvn clean package
Importante
In questo stesso file authentication.properties è disponibile un'impostazione per .aad.secret
Non è consigliabile distribuire questo valore in servizio app. Nessuno dei due è consigliabile lasciare questo valore nel codice e potenzialmente eseguirne il push nel repository Git. Per rimuovere questo valore segreto dal codice, è possibile trovare indicazioni più dettagliate nella sezione Deploy to servizio app - Remove secret (Distribuisci in servizio app - Rimuovi segreto). Questo materiale sussidiario aggiunge passaggi aggiuntivi per il push del valore del segreto in Key Vault e per l'uso dei riferimenti all'insieme di credenziali delle chiavi.
Aggiornare la registrazione dell'app Microsoft Entra ID
Poiché l'URI di reindirizzamento cambia nell'app distribuita in app Azure Servizio, è anche necessario modificare l'URI di reindirizzamento nella registrazione dell'app Microsoft Entra ID. Attenersi alla seguente procedura per apportare questa modifica:
Passare alla pagina Registrazioni app di Microsoft Identity Platform per sviluppatori.
Usare la casella di ricerca per cercare la registrazione dell'app,
java-servlet-webapp-authentication
ad esempio .Aprire la registrazione dell'app selezionandone il nome.
Seleziona Autenticazione dal menu.
Nella sezione URI di reindirizzamento Web - selezionare Aggiungi URI.
Compilare l'URI dell'app, aggiungendo
/auth/redirect
, ad esempio .https://<your-app-name>.azurewebsites.net/auth/redirect
Seleziona Salva.
Distribuire l'app
È ora possibile distribuire l'app nel servizio app Azure. Usare il comando seguente per assicurarsi di aver eseguito l'accesso all'ambiente Azure per eseguire la distribuzione:
az login
Con tutta la configurazione pronta nel file pom.xml , è ora possibile usare il comando seguente per distribuire l'app Java in Azure:
mvn package azure-webapp:deploy
Al termine della distribuzione, l'applicazione è pronta in http://<your-app-name>.azurewebsites.net/
. Aprire l'URL con il Web browser locale, in cui verrà visualizzata la pagina iniziale dell'applicazione msal4j-servlet-auth
.
Esaminare l'esempio
Per esplorare l'esempio, seguire questa procedura:
- Si noti lo stato di accesso o disconnesso visualizzato al centro della schermata.
- Selezionare il pulsante sensibile al contesto nell'angolo. Questo pulsante legge Accedi quando si esegue l'app per la prima volta.
- Nella pagina successiva seguire le istruzioni e accedere con un account del provider di identità scelto.
- Si noti che il pulsante sensibile al contesto ora indica Disconnetti e visualizza il nome utente.
- Selezionare ID Token Details (Dettagli token ID) per visualizzare alcune delle attestazioni decodificate del token ID.
- Hai anche la possibilità di modificare il tuo profilo. Selezionare il collegamento per modificare i dettagli, ad esempio il nome visualizzato, il luogo di residenza e la professione.
- Usare il pulsante nell'angolo per disconnettersi.
- Dopo la disconnessione, passare all'URL seguente per la pagina dei dettagli del token:
http://localhost:8080/ms-identity-b2c-java-servlet-webapp-authentication/auth_token_details
. Qui è possibile osservare come l'app visualizza un401: unauthorized
errore anziché le attestazioni del token ID.
Informazioni sul codice
Questo esempio illustra come usare MSAL4J per consentire agli utenti di accedere al tenant di Azure AD B2C.
Contenuto
La tabella seguente illustra il contenuto della cartella del progetto di esempio:
File/cartella | Descrizione |
---|---|
AuthHelper.java | Funzioni helper per l'autenticazione. |
Config.java | Viene eseguito all'avvio e configura il lettore e il logger delle proprietà. |
authentication.properties | Microsoft Entra ID e configurazione del programma. |
AuthenticationFilter.java | Reindirizza le richieste non autenticate alle risorse protette a una pagina 401. |
MsalAuthSession | Creazione di un'istanza di con un oggetto HttpSession . Archivia tutti gli attributi di sessione correlati a MSAL nell'attributo di sessione. |
____Servlet.java | Tutti gli endpoint disponibili sono definiti nelle classi .java che terminano in ____Servlet.java. |
CHANGELOG.md | Elenco delle modifiche apportate all'esempio. |
CONTRIBUTING.md | Linee guida per contribuire all'esempio. |
LICENZA | Licenza per l'esempio. |
ConfidentialClientApplication
Viene creata un'istanza ConfidentialClientApplication
nel file AuthHelper.java , come illustrato nell'esempio seguente. Questo oggetto consente di creare l'URL di autorizzazione di Azure AD B2C e consente anche di scambiare il token di autenticazione per un token di accesso.
IClientSecret secret = ClientCredentialFactory.createFromSecret(SECRET);
confClientInstance = ConfidentialClientApplication
.builder(CLIENT_ID, secret)
.b2cAuthority(AUTHORITY + policy)
.build();
Per la creazione di istanze vengono usati i parametri seguenti:
- ID client dell'app.
- Segreto client, che è un requisito per le applicazioni client riservate.
- Autorità di Azure AD B2C concatenata con l'opzione appropriata
UserFlowPolicy
per l'iscrizione, l'accesso, la modifica del profilo o la reimpostazione della password.
In questo esempio questi valori vengono letti dal file authentication.properties usando un lettore di proprietà nel file Config.java .
Procedura
I passaggi seguenti forniscono una procedura dettagliata delle funzionalità dell'app:
Il primo passaggio del processo di accesso consiste nell'inviare una richiesta all'endpoint per il
/authorize
tenant di Azure Active Directory B2C. L'istanza DI MSAL4JConfidentialClientApplication
viene usata per costruire un URL della richiesta di autorizzazione e l'app reindirizza il browser a questo URL, come illustrato nell'esempio seguente:final ConfidentialClientApplication client = getConfidentialClientInstance(policy); final AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters .builder(REDIRECT_URI, Collections.singleton(SCOPES)).responseMode(ResponseMode.QUERY) .prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build(); final String redirectUrl = client.getAuthorizationRequestUrl(parameters).toString(); Config.logger.log(Level.INFO, "Redirecting user to {0}", redirectUrl); resp.setStatus(302); resp.sendRedirect(redirectUrl);
L'elenco seguente descrive le funzionalità di questo codice:
AuthorizationRequestUrlParameters
: parametri che devono essere impostati per compilare un oggetto AuthorizationRequestUrl.REDIRECT_URI
: dove Azure AD B2C reindirizza il browser, insieme al codice di autenticazione, dopo aver raccolto le credenziali utente.SCOPES
: gli ambiti sono autorizzazioni richieste dall'applicazione.In genere, i tre ambiti
openid profile offline_access
sarebbero sufficienti per ricevere una risposta del token ID. Tuttavia, MSAL4J richiede che tutte le risposte di Azure AD B2C contengano anche un token di accesso.Affinché Azure AD B2C distribuisca un token di accesso e un token ID, la richiesta deve includere un ambito di risorsa aggiuntivo. Poiché questa app non richiede effettivamente un ambito di risorsa esterna, aggiunge il proprio ID client come quarto ambito per ricevere un token di accesso.
È possibile trovare un elenco completo degli ambiti richiesti dall'app nel file authentication.properties .
ResponseMode.QUERY
: Azure AD B2C può restituire la risposta come parametri del modulo in una richiesta HTTP POST o come parametri della stringa di query in una richiesta HTTP GET.Prompt.SELECT_ACCOUNT
: Azure AD B2C deve chiedere all'utente di selezionare l'account in cui intende eseguire l'autenticazione.state
: variabile univoca impostata dall'app nella sessione in ogni richiesta di token e eliminata dopo aver ricevuto il callback di reindirizzamento di Azure AD B2C corrispondente. La variabile di stato garantisce che le richieste di Azure AD B2C a/auth_redirect endpoint
siano effettivamente provenienti da richieste di autorizzazione di Azure AD B2C provenienti da questa app e da questa sessione, impedendo così attacchi CSRF. Questa operazione viene eseguita nel file AADRedirectServlet.java .nonce
: variabile univoca impostata dall'app nella sessione in ogni richiesta di token e eliminata definitivamente dopo aver ricevuto il token corrispondente. Questo nonce viene trascritto nei token risultanti erogati da Azure AD B2C, assicurando in tal modo che non si verifichi alcun attacco di riproduzione del token.
L'utente riceve una richiesta di accesso da Azure Active Directory B2C. Se il tentativo di accesso ha esito positivo, il browser dell'utente viene reindirizzato all'endpoint di reindirizzamento dell'app. Una richiesta valida a questo endpoint contiene un codice di autorizzazione.
L'istanza
ConfidentialClientApplication
scambia quindi questo codice di autorizzazione per un token ID e un token di accesso da Azure Active Directory B2C, come illustrato nell'esempio seguente:final AuthorizationCodeParameters authParams = AuthorizationCodeParameters .builder(authCode, new URI(REDIRECT_URI)) .scopes(Collections.singleton(SCOPES)).build(); final ConfidentialClientApplication client = AuthHelper .getConfidentialClientInstance(policy); final Future<IAuthenticationResult> future = client.acquireToken(authParams); final IAuthenticationResult result = future.get();
L'elenco seguente descrive le funzionalità di questo codice:
AuthorizationCodeParameters
: parametri che devono essere impostati per scambiare il codice di autorizzazione per un ID e/o un token di accesso.authCode
: codice di autorizzazione ricevuto nell'endpoint di reindirizzamento.REDIRECT_URI
: l'URI di reindirizzamento usato nel passaggio precedente deve essere passato di nuovo.SCOPES
: gli ambiti usati nel passaggio precedente devono essere passati di nuovo.
Se
acquireToken
ha esito positivo, le attestazioni del token vengono estratte e l'attestazione nonce viene convalidata in base al nonce archiviato nella sessione, come illustrato nell'esempio seguente:parseJWTClaimsSetAndStoreResultInSession(msalAuth, result, serializedTokenCache); validateNonce(msalAuth) processSuccessfulAuthentication(msalAuth);
Se il nonce viene convalidato correttamente, lo stato di autenticazione viene inserito in una sessione lato server, sfruttando i metodi esposti dalla
MsalAuthSession
classe , come illustrato nell'esempio seguente:msalAuth.setAuthenticated(true); msalAuth.setUsername(msalAuth.getIdTokenClaims().get("name"));
Ulteriori informazioni
- Informazioni su Azure Active Directory B2C
- Tipi di applicazione che possono essere usati in Active Directory B2C
- Raccomandazioni e procedure consigliate per Azure Active Directory B2C
- Sessione di Azure AD B2C
- Microsoft Authentication Library (MSAL) per Java
Per altre informazioni sul funzionamento dei protocolli OAuth 2.0 in questo scenario e in altri scenari, vedere Scenari di autenticazione per Microsoft Entra ID.