Övning – Logga in användare med MSAL

Slutförd

I den här övningen använder du Microsoft Authentication Library for Java (MSAL4J) för att lägga till autentisering i ett Java-exempelwebbprogram och tillåta användare att logga in med sina Microsoft Entra-konton.

Exempelprogrammet som du använder i den här övningen är ett Java servlet-program som gör det möjligt för användare att logga in och visa användarnamn och grundläggande profilinformation. Du kan också anropa Microsoft Graph API för att visa viss användarinformation.

Skapa ett Java-webbprogram

Från gränssnittet eller kommandoraden:

  1. Skapa en mapp för programmet.

    mkdir ~/javawebapp
    
  2. Klona exempelprogrammet från GitHub-lagringsplatsen till den nya mappen.

    git clone https://github.com/Azure-Samples/ms-identity-java-servlet-webapp-authentication.git ~/javawebapp
    
  3. Ändra till mappen där exempelprogrammet för den här övningen finns.

    cd ~/javawebapp/ms-identity-java-servlet-webapp-authentication/2-Authorization-I/call-graph
    

Konfigurera programmet

Om du vill konfigurera koden öppnar du programprojektet i önskad IDE som IntelliJ eller VS Code.

  1. Öppna filen ./src/main/resources/authentication.properties.

  2. Leta reda på strängen aad.authority{enter-your-tenant-id-here}i egenskapen . Ersätt det befintliga värdet med ID-värdet för Katalog (klientorganisation) – som visas i följande bild – eftersom appen registrerades med alternativet Konton i den här organisationskatalogen.

  3. Leta reda på aad.clientId strängen {enter-your-client-id-here} i egenskapen och ersätt det befintliga värdet med ID-värdet för program (klient) – clientId värdet – för det registrerade program som kopierats från Azure Portal.

    Skärmbild som visar app-ID för en app som registrerats med Microsoft Entra-ID på Azure Portal.

  4. Leta reda på aad.secret strängen {enter-your-client-secret-here} i egenskapen och ersätt det befintliga värdet med det nyckelvärde som du sparade när appen skapades i Azure Portal.

Kör appen

  1. Kontrollera att Tomcat-servern körs och att du har behörighet att distribuera en webbapp till den. Kontrollera att serverns värdadress är http://localhost:8080.

  2. Kompilera och paketera projektet med maven:

    cd ~/javawebapp/2-Authorization-I/call-graph
    mvn clean package
    
  3. Hitta den resulterande .war-filen./target/msal4j-servlet-graph.war. Om du vill distribuera till Tomcat kopierar du den här .war-filen till katalogen /webapps/ i tomcat-installationskatalogen och startar Tomcat-servern.

  4. Öppna din webbläsare och gå till http://localhost:8080/msal4j-servlet-graph/. Du omdirigeras för att logga in med Microsoft Entra-ID. Vid lyckad inloggning bör du se en sida som liknar följande:

    Skärmbild som visar användarnamnet som visas på sidan när du har loggat in i exempelprogrammet.

  5. Välj knappen ID-tokeninformation för att se några av ID-tokens avkodade anspråk.

Översikt över autentiseringskod

Du hittar det mesta av autentiseringskoden i exempelprogrammet under projektets java/com/microsoft/azuresamples/msal4j/ katalog. Den innehåller flera servletar som tillhandahåller autentiseringsslutpunkterna i programmet för att logga in, logga ut och hantera återanropet från Microsoft Entra-ID. Dessa servlets använder hjälpklasserna i katalogen java/com/microsoft/azuresamples/msal4j/helpers/ för att anropa de autentiseringsmetoder som tillhandahålls av MSAL. Det finns ett servlet-filter definierat i AuthenticationFilter.java som omdirigerar oautentiserade begäranden till skyddade vägar till en 401-felsida för obehörig HTTP.

Om du vill lägga till autentisering i ditt program måste du inkludera servlet-klasserna under java/com/microsoft/azuresamples/msal4j/authservlets och java/com/microsoft/azuresamples/msal4j/authwebapp kataloger, hjälpklasserna i katalogen java/com/microsoft/azuresamples/msal4j/helpers/ och autentiseringsservlet-filtret AuthenticationFilter.java i dina projekt. Här följer mer information om MSAL-autentiseringskoden.

  1. MSAL4J är tillgängligt på Maven. Du måste lägga till MSAL4J som ett beroende i projektets pom.xml-fil :

    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>msal4j</artifactId>
        <version>1.17.2</version>
    </dependency>
    
  2. Det första steget i inloggningsprocessen är att skicka en begäran till Microsoft Entra-klientorganisationens /authorize slutpunkt. MSAL4J-instansen ConfidentialClientApplication används för att skapa en URL för auktoriseringsbegäran. Appen omdirigerar webbläsaren till den här URL:en, där användaren loggar in. Följande kod är ett utdrag från implementeringen av redirectToAuthorizationEndpoint metoden i AuthHelper klassen.

    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: Parametrar som måste anges för att skapa en AuthorizationRequestUrl.
    • REDIRECT_URI: Omdirigerings-URI:n är den URI som identitetsprovidern skickar tillbaka säkerhetstoken till. Microsoft Entra-ID omdirigerar webbläsaren – tillsammans med autentiseringskod – till den här URI:n efter att användarens autentiseringsuppgifter har samlats in. Den måste matcha omdirigerings-URI:n i Microsoft Entra-appregistreringen.
    • SCOPES: Omfång är behörigheter som begärs av programmet. Normalt räcker det med de tre omfången openid profile offline_access för att ta emot ett ID-tokensvar för en användarinloggning och anges som standard av MSAL.
  3. Användaren får en inloggningsprompt av Microsoft Entra-ID. Om inloggningsförsöket lyckas omdirigeras användarens webbläsare till appens omdirigeringsslutpunkt med en giltig auktoriseringskod i slutpunkten. Instansen ConfidentialClientApplication utbyter sedan den här auktoriseringskoden mot en ID-token och åtkomsttoken från Microsoft Entra-ID. Följande kod är ett utdrag från implementeringen av processAADCallback metoden i AuthHelper klassen.

    // 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: Parametrar som måste anges för att kunna byta auktoriseringskoden mot ett ID och/eller en åtkomsttoken.
    • authCode: Auktoriseringskoden som togs emot vid omdirigeringsslutpunkten.
    • REDIRECT_URI: Omdirigerings-URI:n som användes i föregående steg måste skickas igen.
    • SCOPES: Omfången som användes i föregående steg måste skickas igen.
  4. Om acquireToken det lyckas extraheras tokenanspråken. Om nonce-kontrollen godkänns placeras resultatet i context – en instans av IdentityContextData – och sparas i sessionen. Programmet kan sedan instansiera detta från sessionen – som en instans av IdentityContextAdapterServlet – när det behöver åtkomst till det:

    // 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());