練習 - 使用 MSAL 登入使用者
在此練習中,您將使用適用於 Java 的 Microsoft 驗證程式庫 (MSAL4J) 在範例 Java Web 應用程式中新增驗證,讓使用者能夠使用其 Microsoft Entra 帳戶進行登入。
此練習中使用的範例應用程式是 Java Servlet 應用程式,可讓使用者登入並顯示使用者名稱和基本設定檔資訊。 您可藉此呼叫 Microsoft Graph API,以顯示一些使用者資訊。
建立 JAVA Web 應用程式
從殼層或命令列:
建立應用程式的資料夾。
mkdir ~/javawebapp
將範例應用程式從 GitHub 存放庫複製到新資料夾。
git clone https://github.com/Azure-Samples/ms-identity-java-servlet-webapp-authentication.git ~/javawebapp
切換至此練習的範例應用程式所在的資料夾。
cd ~/javawebapp/ms-identity-java-servlet-webapp-authentication/2-Authorization-I/call-graph
設定應用程式
若要設定程式碼,請在您慣用的 IDE 中開啟應用程式專案,例如 IntelliJ 或 VS Code。
開啟 ./src/main/resources/authentication.properties 檔案。
在
aad.authority
屬性中,尋找字串{enter-your-tenant-id-here}
。 將現有值取代為 目錄 (租用戶) 識別碼值 (如下圖所示),因為應用程式是使用 [僅限此組織目錄中的帳戶] 選項註冊。在
aad.clientId
屬性中,找到字串{enter-your-client-id-here}
,並將現有值取代為已註冊並從 Azure 入口網站複製的應用程式的應用程式 (用戶端) 識別碼值 -clientId
值。在
aad.secret
屬性中,尋找字串{enter-your-client-secret-here}
,並將現有值取代為您在 Azure 入口網站中建立應用程式時所儲存的 [金鑰] 值。
執行應用程式
確定您的 Tomcat 伺服器正在執行,且您有權將 Web 應用程式部署至該伺服器。 確定您的伺服器主機位址是
http://localhost:8080
。使用 Maven 編譯並封裝專案:
cd ~/javawebapp/2-Authorization-I/call-graph mvn clean package
在 ./target/msal4j-servlet-graph.war 尋找產生的 .war 檔案。 若要部署至 Tomcat,請將這個 .war 檔案複製到 Tomcat 安裝目錄中的 /webapps/ 目錄,然後啟動 Tomcat 伺服器。
請開啟瀏覽器,然後瀏覽至
http://localhost:8080/msal4j-servlet-graph/
。 系統會將您重新導向至使用 Microsoft Entra ID 登入。 成功登入時,您應該會看到如下的頁面:選取 [識別碼權杖詳細資料] 按鈕,以查看某些識別碼權杖的解碼宣告。
驗證碼概觀
您可以在專案 java/com/microsoft/azuresamples/msal4j/
目錄下的範例應用程式中找到大部分的驗證碼。 其中包含多個 Servlet,可在應用程式中提供驗證端點,用於登入、登出,以及處理來自 Microsoft Entra ID 的重新導向回撥。 這些 servlet 會使用目錄 java/com/microsoft/azuresamples/msal4j/helpers/ 中的協助程式類別來呼叫 MSAL 提供的驗證方法。 在 AuthenticationFilter.java
中定義的 Servlet 篩選會將未經驗證的要求重新導向至受保護的路由,而連至 401 未授權的 HTTP 錯誤頁面。
若要將驗證新增至您的應用程式,您必須將 Servlet 類別包含在 java/com/microsoft/azuresamples/msal4j/authservlets
和 java/com/microsoft/azuresamples/msal4j/authwebapp
目錄下、將協助程式類別包含在目錄 java/com/microsoft/azuresamples/msal4j/helpers/ 中,並將驗證 Servlet 篩選 AuthenticationFilter.java
包含在您的專案中。 以下是 MSAL 驗證碼的詳細資料。
MSAL4J 可在 Maven 上取得。 您必須在專案的 pom.xml 檔案中將 MSAL4J 新增為相依性:
<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>msal4j</artifactId> <version>1.17.2</version> </dependency>
登入程序的第一個步驟是將要求傳送至 Microsoft Entra 租用戶的
/authorize
端點。 可利用 MSAL4JConfidentialClientApplication
執行個體來建構授權要求 URL。 應用程式會將瀏覽器重新導向至此 URL,這是使用者登入的位置。 下列程式碼是AuthHelper
類別中redirectToAuthorizationEndpoint
方法實作的摘錄。final ConfidentialClientApplication client = getConfidentialClientInstance(); AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters .builder(Config.REDIRECT_URI, Collections.singleton(Config.SCOPES)) .responseMode(ResponseMode.QUERY).prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build(); final String authorizeUrl = client.getAuthorizationRequestUrl(parameters).toString(); contextAdapter.redirectUser(authorizeUrl);
AuthorizationRequestUrlParameters
:必須設定才能建置AuthorizationRequestUrl
的參數。REDIRECT_URI
:重新導向 URI 是識別提供者將傳回安全性權杖的目標 URI。 Microsoft Entra ID 會在收集使用者認證後,將瀏覽器以及驗證碼重新導向至此 URI。 這必須符合 Microsoft Entra 應用程式註冊中的重新導向 URI。SCOPES
:範圍是應用程式所要求的權限。 一般來說,openid profile offline_access
這三個範圍即足以接收使用者登入的識別碼權杖回應,而 MSAL 依預設會設定這些範圍。
使用者會看到 Microsoft Entra ID 發出的登入提示。 如果登入嘗試成功,則會將使用者的瀏覽器重新導向至我們應用程式的重新導向端點 (端點中具有有效的授權碼)。 然後,
ConfidentialClientApplication
執行個體會以此授權碼交換來自 Microsoft Entra ID 的識別碼權杖和存取權杖。 下列程式碼是AuthHelper
類別中processAADCallback
方法實作的摘錄。// First, validate the state, then parse any error codes in response, then extract the authCode. Then: // build the auth code params: final AuthorizationCodeParameters authParams = AuthorizationCodeParameters .builder(authCode, new URI(Config.REDIRECT_URI)).scopes(Collections.singleton(Config.SCOPES)).build(); // Get a client instance and leverage it to acquire the token: final ConfidentialClientApplication client = AuthHelper.getConfidentialClientInstance(); final IAuthenticationResult result = client.acquireToken(authParams).get();
AuthorizationCodeParameters
:必須設定才能以授權碼交換識別碼和/或存取權杖的參數。authCode
:在重新導向端點接收到的授權碼。REDIRECT_URI
:必須再次傳入在先前的步驟中使用的重新導向 URI。SCOPES
:必須再次傳入在先前的步驟中使用的範圍。
如果
acquireToken
成功,則會擷取權杖宣告。 如果通過 nonce 檢查,結果將會放在context
(IdentityContextData
的執行個體) 中,並儲存至工作階段。 然後,每當應用程式需要存取時,就可以從工作階段 (藉由IdentityContextAdapterServlet
的執行個體) 將其具現化:// parse IdToken claims from the IAuthenticationResult: // (the next step - validateNonce - requires parsed claims) context.setIdTokenClaims(result.idToken()); // if nonce is invalid, stop immediately! this could be a token replay! // if validation fails, throws exception and cancels auth: validateNonce(context); // set user to authenticated: context.setAuthResult(result, client.tokenCache().serialize());