> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Ajoutez l’authentification Auth0, la déconnexion et le profil utilisateur à une application Web Java EE 8 à l’aide de l’API de sécurité

# Ajouter l’authentification à votre application Java EE

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<HowToSchema />

<Accordion title="Utilisez l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant de programmation par IA comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification Auth0 en quelques minutes à l’aide des [agent skills](https://agentskills.io/home).

  **Installer :**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-java-mvc-common
  ```

  **Ensuite, demandez à votre assistant IA :**

  ```text theme={null}
  Add Auth0 authentication to my Java EE app
  ```

  Votre assistant IA créera automatiquement votre application Auth0, récupérera les identifiants, ajoutera la dépendance au SDK Auth0 Java MVC Commons, configurera l’authentification avec l’API de sécurité Java EE 8 et mettra en œuvre les flux de connexion et de déconnexion. [Documentation complète sur les agent skills →](/fr-CA/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **Prérequis :**

  * [Java Development Kit (JDK)](https://www.oracle.com/java/technologies/downloads/) 11 ou une version ultérieure
  * [Apache Maven](https://maven.apache.org/download.cgi) 3.x
  * Un serveur d’applications compatible avec Java EE 8 (p. ex., [WildFly](https://www.wildfly.org/) 14+, [Payara](https://www.payara.fish/) 5+ ou [GlassFish](https://glassfish.org/) 5+)
  * Un compte Auth0 — [inscrivez-vous gratuitement](https://auth0.com/signup)
</Note>

<div id="get-started">
  ## Commencer
</div>

Auth0 vous permet d’ajouter rapidement l’authentification à votre application et d’accéder aux renseignements du profil utilisateur. Ce guide explique comment intégrer Auth0 à toute application Java EE, nouvelle ou existante, à l’aide du SDK `auth0-java-mvc-common` et de l’API de sécurité Java EE 8.

<Steps>
  <Step title="Créer un nouveau projet" stepNumber={1}>
    Générez un nouveau projet Maven WAR :

    ```shellscript theme={null}
    mvn archetype:generate \
      -DgroupId=com.auth0.example \
      -DartifactId=java-ee-auth0-app \
      -DarchetypeArtifactId=maven-archetype-webapp \
      -DinteractiveMode=false
    ```

    Accédez au dossier du projet :

    ```shellscript theme={null}
    cd java-ee-auth0-app
    ```

    Créez les répertoires source Java :

    ```shellscript theme={null}
    mkdir -p src/main/java/com/auth0/example/security
    mkdir -p src/main/java/com/auth0/example/web
    mkdir -p src/main/webapp/WEB-INF/jsp
    ```
  </Step>

  <Step title="Installer le SDK Auth0" stepNumber={2}>
    Remplacez le contenu de votre `pom.xml` par le suivant :

    ```xml pom.xml expandable lines theme={null}
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
             http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.auth0.example</groupId>
        <artifactId>java-ee-auth0-app</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>

        <properties>
            <maven.compiler.source>11</maven.compiler.source>
            <maven.compiler.target>11</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <version.wildfly>23.0.2.Final</version.wildfly>
        </properties>

        <dependencies>
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>mvc-auth-commons</artifactId>
                <version>[1.0, 2.0)</version>
            </dependency>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-api</artifactId>
                <version>8.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.security.enterprise</groupId>
                <artifactId>javax.security.enterprise-api</artifactId>
                <version>1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.16.0</version>
            </dependency>
        </dependencies>

        <build>
            <finalName>java-ee-auth0-app</finalName>
            <plugins>
                <plugin>
                    <groupId>org.wildfly.plugins</groupId>
                    <artifactId>wildfly-maven-plugin</artifactId>
                    <version>4.2.0.Final</version>
                    <configuration>
                        <version>${version.wildfly}</version>
                        <javaOpts>
                            <javaOpt>-Djboss.http.port=8080</javaOpt>
                        </javaOpts>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    ```

    Les dépendances `javaee-api` et `javax.security.enterprise-api` sont `provided`, car le serveur d’applications Java EE 8 fournit leurs implémentations à l’exécution.
  </Step>

  <Step title="Configurez votre application Auth0" stepNumber={3}>
    <Tabs>
      <Tab title="Auth0 Dashboard">
        1. Accédez au [Auth0 Dashboard](https://manage.auth0.com/#/applications) et allez à **Applications > Applications > Create Application**.
        2. Entrez un nom pour votre application (p. ex., "Mon application Java EE").
        3. Sélectionnez **Regular Web Applications** comme type d’application.
        4. Choisissez **Create**.
        5. Ouvrez l’onglet **Settings**.
        6. Prenez en note les valeurs **Domain**, **Client ID** et **Client Secret**.
        7. Faites défiler la page jusqu’à **Application URIs** et définissez :
           * **Allowed Callback URLs**: `http://localhost:8080/callback`
           * **Allowed Logout URLs**: `http://localhost:8080/`
        8. Choisissez **Save Changes**.
      </Tab>
    </Tabs>

    <Info>
      Assurez-vous de [configurer des connexions](https://auth0.com/docs/get-started/applications/set-up-database-connections) pour votre application afin que les utilisateurs puissent se connecter à l’aide du fournisseur d’identité de leur choix.
    </Info>
  </Step>

  <Step title="Configurer l’authentification" stepNumber={4}>
    Mettez à jour votre `web.xml` pour stocker la configuration Auth0 sous forme d'entrées d'environnement JNDI. Remplacez les valeurs fictives par le **Domaine**, l'**ID client** et le **Secret client** figurant dans les paramètres de l'application Auth0. Créez un fichier `jboss-web.xml` pour configurer le domaine de sécurité JASPIC requis par l'API de sécurité Java EE 8, un bean CDI `Auth0AuthenticationConfig.java` pour lire la configuration depuis JNDI, et un producteur CDI `Auth0AuthenticationProvider.java` pour construire l'`AuthenticationController`.

    <Info>
      N’incluez pas `https://` dans la valeur `auth0.domain`. Utilisez uniquement le domaine et la région. Par exemple : `dev-abc123.us.auth0.com`.
    </Info>

    <AuthCodeGroup>
      ```xml src/main/webapp/WEB-INF/web.xml expandable lines theme={null}
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
               http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
               version="3.1">

          <env-entry>
              <env-entry-name>auth0.domain</env-entry-name>
              <env-entry-type>java.lang.String</env-entry-type>
              <env-entry-value>YOUR_AUTH0_DOMAIN</env-entry-value>
          </env-entry>
          <env-entry>
              <env-entry-name>auth0.clientId</env-entry-name>
              <env-entry-type>java.lang.String</env-entry-type>
              <env-entry-value>YOUR_CLIENT_ID</env-entry-value>
          </env-entry>
          <env-entry>
              <env-entry-name>auth0.clientSecret</env-entry-name>
              <env-entry-type>java.lang.String</env-entry-type>
              <env-entry-value>YOUR_CLIENT_SECRET</env-entry-value>
          </env-entry>
          <env-entry>
              <env-entry-name>auth0.scope</env-entry-name>
              <env-entry-type>java.lang.String</env-entry-type>
              <env-entry-value>openid profile email</env-entry-value>
          </env-entry>
      </web-app>
      ```

      ```xml src/main/webapp/WEB-INF/jboss-web.xml lines theme={null}
      <?xml version="1.0"?>
      <jboss-web>
          <security-domain>jaspitest</security-domain>
          <context-root>/</context-root>
      </jboss-web>
      ```

      ```java src/main/java/com/auth0/example/security/Auth0AuthenticationConfig.java expandable lines theme={null}
      package com.auth0.example.security;

      import javax.annotation.PostConstruct;
      import javax.enterprise.context.ApplicationScoped;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;

      @ApplicationScoped
      public class Auth0AuthenticationConfig {

          private String domain;
          private String clientId;
          private String clientSecret;
          private String scope;

          @PostConstruct
          public void init() {
              try {
                  Context env = (Context) new InitialContext().lookup("java:comp/env");
                  this.domain = (String) env.lookup("auth0.domain");
                  this.clientId = (String) env.lookup("auth0.clientId");
                  this.clientSecret = (String) env.lookup("auth0.clientSecret");
                  this.scope = (String) env.lookup("auth0.scope");
              } catch (NamingException ne) {
                  throw new IllegalArgumentException(
                          "Unable to lookup auth0 configuration properties from web.xml", ne);
              }

              if (this.domain == null || this.clientId == null
                      || this.clientSecret == null || this.scope == null) {
                  throw new IllegalArgumentException(
                          "domain, clientId, clientSecret, and scope must be set in web.xml");
              }
          }

          public String getDomain() { return domain; }
          public String getClientId() { return clientId; }
          public String getClientSecret() { return clientSecret; }
          public String getScope() { return scope; }
      }
      ```

      ```java src/main/java/com/auth0/example/security/Auth0AuthenticationProvider.java expandable lines theme={null}
      package com.auth0.example.security;

      import com.auth0.AuthenticationController;
      import com.auth0.jwk.JwkProvider;
      import com.auth0.jwk.JwkProviderBuilder;

      import javax.enterprise.context.ApplicationScoped;
      import javax.enterprise.inject.Produces;

      @ApplicationScoped
      public class Auth0AuthenticationProvider {

          @Produces
          public AuthenticationController authenticationController(Auth0AuthenticationConfig config) {
              JwkProvider jwkProvider = new JwkProviderBuilder(config.getDomain()).build();
              return AuthenticationController.newBuilder(
                              config.getDomain(), config.getClientId(), config.getClientSecret())
                      .withJwkProvider(jwkProvider)
                      .build();
          }
      }
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Implémenter la sécurité Java EE" stepNumber={5}>
    L’API de sécurité de Java EE 8 utilise `HttpAuthenticationMechanism` pour gérer l’authentification. Vous devez fournir des implémentations personnalisées de plusieurs interfaces de sécurité. L’annotation `@AutoApplySession` permet au conteneur de créer une session pour l’utilisateur authentifié afin que celui-ci reste connecté d’une requête à l’autre.

    <AuthCodeGroup>
      ```java src/main/java/com/auth0/example/security/Auth0JwtPrincipal.java expandable lines theme={null}
      package com.auth0.example.security;

      import com.auth0.jwt.interfaces.DecodedJWT;

      import javax.security.enterprise.CallerPrincipal;

      public class Auth0JwtPrincipal extends CallerPrincipal {

          private final DecodedJWT idToken;

          Auth0JwtPrincipal(DecodedJWT idToken) {
              super(idToken.getClaim("name").asString());
              this.idToken = idToken;
          }

          public DecodedJWT getIdToken() {
              return this.idToken;
          }
      }
      ```

      ```java src/main/java/com/auth0/example/security/Auth0JwtCredential.java expandable lines theme={null}
      package com.auth0.example.security;

      import com.auth0.jwt.JWT;
      import com.auth0.jwt.interfaces.DecodedJWT;

      import javax.security.enterprise.credential.Credential;

      class Auth0JwtCredential implements Credential {

          private Auth0JwtPrincipal auth0JwtPrincipal;

          Auth0JwtCredential(String token) {
              DecodedJWT decodedJWT = JWT.decode(token);
              this.auth0JwtPrincipal = new Auth0JwtPrincipal(decodedJWT);
          }

          Auth0JwtPrincipal getAuth0JwtPrincipal() {
              return auth0JwtPrincipal;
          }
      }
      ```

      ```java src/main/java/com/auth0/example/security/Auth0JwtIdentityStore.java expandable lines theme={null}
      package com.auth0.example.security;

      import javax.enterprise.context.ApplicationScoped;
      import javax.security.enterprise.credential.Credential;
      import javax.security.enterprise.identitystore.CredentialValidationResult;
      import javax.security.enterprise.identitystore.IdentityStore;

      @ApplicationScoped
      public class Auth0JwtIdentityStore implements IdentityStore {

          @Override
          public CredentialValidationResult validate(final Credential credential) {
              CredentialValidationResult result = CredentialValidationResult.NOT_VALIDATED_RESULT;

              if (credential instanceof Auth0JwtCredential) {
                  Auth0JwtCredential auth0JwtCredential = (Auth0JwtCredential) credential;
                  result = new CredentialValidationResult(auth0JwtCredential.getAuth0JwtPrincipal());
              }

              return result;
          }
      }
      ```

      ```java src/main/java/com/auth0/example/security/Auth0AuthenticationMechanism.java expandable lines theme={null}
      package com.auth0.example.security;

      import com.auth0.AuthenticationController;
      import com.auth0.IdentityVerificationException;
      import com.auth0.Tokens;

      import javax.enterprise.context.ApplicationScoped;
      import javax.inject.Inject;
      import javax.security.enterprise.AuthenticationException;
      import javax.security.enterprise.AuthenticationStatus;
      import javax.security.enterprise.authentication.mechanism.http.AutoApplySession;
      import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
      import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext;
      import javax.security.enterprise.identitystore.CredentialValidationResult;
      import javax.security.enterprise.identitystore.IdentityStoreHandler;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      @ApplicationScoped
      @AutoApplySession
      public class Auth0AuthenticationMechanism implements HttpAuthenticationMechanism {

          private final AuthenticationController authenticationController;
          private final IdentityStoreHandler identityStoreHandler;

          @Inject
          Auth0AuthenticationMechanism(AuthenticationController authenticationController,
                                       IdentityStoreHandler identityStoreHandler) {
              this.authenticationController = authenticationController;
              this.identityStoreHandler = identityStoreHandler;
          }

          @Override
          public AuthenticationStatus validateRequest(HttpServletRequest httpServletRequest,
                                                      HttpServletResponse httpServletResponse,
                                                      HttpMessageContext httpMessageContext)
                  throws AuthenticationException {

              if (isCallbackRequest(httpServletRequest)) {
                  try {
                      Tokens tokens = authenticationController.handle(
                              httpServletRequest, httpServletResponse);
                      Auth0JwtCredential auth0JwtCredential =
                              new Auth0JwtCredential(tokens.getIdToken());
                      CredentialValidationResult result =
                              identityStoreHandler.validate(auth0JwtCredential);
                      return httpMessageContext.notifyContainerAboutLogin(result);
                  } catch (IdentityVerificationException e) {
                      return httpMessageContext.responseUnauthorized();
                  }
              }

              return httpMessageContext.doNothing();
          }

          private boolean isCallbackRequest(HttpServletRequest request) {
              return request.getServletPath().equals("/callback")
                      && request.getParameter("code") != null;
          }
      }
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Ajouter les fonctionnalités de connexion et de déconnexion" stepNumber={6}>
    Créez les servlets de connexion, de callback et de déconnexion. Le `LoginServlet` génère l’URL d’autorisation d’Auth0 et redirige l’utilisateur. Le `CallbackServlet` traite la redirection après l’authentification — `Auth0AuthenticationMechanism` intercepte d’abord cette requête pour échanger le code d’autorisation contre des jetons; le servlet n’a donc qu’à effectuer la redirection. Le `LogoutServlet` invalide la session et redirige vers le point de terminaison de déconnexion d’Auth0.

    <AuthCodeGroup>
      ```java src/main/java/com/auth0/example/web/LoginServlet.java expandable lines theme={null}
      package com.auth0.example.web;

      import com.auth0.AuthenticationController;
      import com.auth0.example.security.Auth0AuthenticationConfig;

      import javax.inject.Inject;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;

      @WebServlet(urlPatterns = "/login")
      public class LoginServlet extends HttpServlet {

          private final Auth0AuthenticationConfig config;
          private final AuthenticationController authenticationController;

          @Inject
          LoginServlet(Auth0AuthenticationConfig config,
                       AuthenticationController authenticationController) {
              this.config = config;
              this.authenticationController = authenticationController;
          }

          @Override
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              String callbackUrl = String.format(
                      "%s://%s:%s%s/callback",
                      request.getScheme(),
                      request.getServerName(),
                      request.getServerPort(),
                      request.getContextPath());

              String authURL = authenticationController
                      .buildAuthorizeUrl(request, response, callbackUrl)
                      .withScope(config.getScope())
                      .build();

              response.sendRedirect(authURL);
          }
      }
      ```

      ```java src/main/java/com/auth0/example/web/CallbackServlet.java expandable lines theme={null}
      package com.auth0.example.web;

      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;

      @WebServlet(urlPatterns = {"/callback"})
      public class CallbackServlet extends HttpServlet {

          @Override
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws IOException {
              response.sendRedirect(request.getContextPath() + "/");
          }
      }
      ```

      ```java src/main/java/com/auth0/example/web/LogoutServlet.java expandable lines theme={null}
      package com.auth0.example.web;

      import com.auth0.example.security.Auth0AuthenticationConfig;

      import javax.inject.Inject;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.net.URLEncoder;

      @WebServlet(urlPatterns = "/logout")
      public class LogoutServlet extends HttpServlet {

          private final Auth0AuthenticationConfig config;

          @Inject
          LogoutServlet(Auth0AuthenticationConfig config) {
              this.config = config;
          }

          @Override
          protected void doGet(final HttpServletRequest request,
                               final HttpServletResponse response)
                  throws ServletException, IOException {
              if (request.getSession() != null) {
                  request.getSession().invalidate();
              }

              String returnUrl = String.format("%s://%s",
                      request.getScheme(), request.getServerName());
              int port = request.getServerPort();
              String scheme = request.getScheme();

              if (("http".equals(scheme) && port != 80)
                      || ("https".equals(scheme) && port != 443)) {
                  returnUrl += ":" + port;
              }

              returnUrl += request.getContextPath() + "/";

              String logoutUrl = String.format(
                      "https://%s/v2/logout?client_id=%s&returnTo=%s",
                      config.getDomain(),
                      config.getClientId(),
                      URLEncoder.encode(returnUrl, "UTF-8"));

              response.sendRedirect(logoutUrl);
          }
      }
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Créer l’interface utilisateur" stepNumber={7}>
    Créez les servlets et les pages JSP pour les vues d'accueil et de profil. Le `HomeServlet` vérifie la présence d'un principal authentifié et définit les revendications de profil sur la requête. Le `ProfileServlet` affiche le profil et les revendications JWT de l'utilisateur, ou redirige vers la page de connexion si l'utilisateur n'est pas authentifié.

    <AuthCodeGroup>
      ```java src/main/java/com/auth0/example/web/HomeServlet.java expandable lines theme={null}
      package com.auth0.example.web;

      import com.auth0.example.security.Auth0JwtPrincipal;

      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.security.Principal;

      @WebServlet(urlPatterns = "")
      public class HomeServlet extends HttpServlet {

          @Override
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              Principal principal = request.getUserPrincipal();

              if (principal instanceof Auth0JwtPrincipal) {
                  Auth0JwtPrincipal auth0JwtPrincipal = (Auth0JwtPrincipal) principal;
                  request.setAttribute("profile", auth0JwtPrincipal.getIdToken().getClaims());
              }

              request.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(request, response);
          }
      }
      ```

      ```java src/main/java/com/auth0/example/web/ProfileServlet.java expandable lines theme={null}
      package com.auth0.example.web;

      import com.auth0.example.security.Auth0JwtPrincipal;
      import com.auth0.jwt.interfaces.DecodedJWT;
      import com.fasterxml.jackson.databind.ObjectMapper;

      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.security.Principal;
      import java.util.Base64;

      @WebServlet(urlPatterns = {"/profile"})
      public class ProfileServlet extends HttpServlet {

          @Override
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              Principal principal = request.getUserPrincipal();

              if (principal instanceof Auth0JwtPrincipal) {
                  Auth0JwtPrincipal auth0JwtPrincipal = (Auth0JwtPrincipal) principal;
                  request.setAttribute("profile", auth0JwtPrincipal.getIdToken().getClaims());

                  String profileJson;
                  try {
                      DecodedJWT idToken = auth0JwtPrincipal.getIdToken();
                      byte[] decodedBytes = Base64.getUrlDecoder().decode(idToken.getPayload());
                      String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
                      ObjectMapper objectMapper = new ObjectMapper();
                      Object json = objectMapper.readValue(decoded, Object.class);
                      profileJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
                  } catch (IOException ioe) {
                      profileJson = "Error converting JWT claims to JSON";
                  }

                  request.setAttribute("profileJson", profileJson);
                  request.getRequestDispatcher("/WEB-INF/jsp/profile.jsp").forward(request, response);
              } else {
                  request.getSession().setAttribute("Referer", request.getRequestURI());
                  request.getRequestDispatcher("/login").forward(request, response);
              }
          }
      }
      ```

      ```html src/main/webapp/WEB-INF/jsp/home.jsp expandable lines theme={null}
      <%@ page contentType="text/html;charset=UTF-8" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>Java EE Auth0 App</title>
          <style>
              body { font-family: sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; }
              nav { display: flex; justify-content: flex-end; gap: 12px; margin-bottom: 40px; align-items: center; }
              nav a { text-decoration: none; padding: 8px 16px; border-radius: 4px; }
              .btn-login { background: #635dff; color: white; }
              .btn-logout { background: #e0e0e0; color: #333; }
              nav img { border-radius: 50%; width: 36px; height: 36px; }
          </style>
      </head>
      <body>
          <nav>
              <c:choose>
                  <c:when test="${not empty profile}">
                      <a href="${pageContext.request.contextPath}/profile">Profile</a>
                      <img src="${profile.get('picture').asString()}" alt="Profile picture"/>
                      <a href="${pageContext.request.contextPath}/logout" class="btn-logout">Logout</a>
                  </c:when>
                  <c:otherwise>
                      <a href="${pageContext.request.contextPath}/login" class="btn-login">Login</a>
                  </c:otherwise>
              </c:choose>
          </nav>

          <h1>Java EE Sample Project</h1>
          <p>This is a sample application that demonstrates an authentication flow for a web application using Java EE.</p>
      </body>
      </html>
      ```

      ```html src/main/webapp/WEB-INF/jsp/profile.jsp expandable lines theme={null}
      <%@ page contentType="text/html;charset=UTF-8" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>Profile - Java EE Auth0 App</title>
          <style>
              body { font-family: sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; }
              nav { display: flex; justify-content: flex-end; gap: 12px; margin-bottom: 40px; align-items: center; }
              nav a { text-decoration: none; padding: 8px 16px; border-radius: 4px; }
              .btn-logout { background: #e0e0e0; color: #333; }
              .profile-header { display: flex; align-items: center; gap: 20px; margin-bottom: 30px; }
              .profile-header img { border-radius: 50%; width: 80px; height: 80px; }
              .profile-header h2 { margin: 0 0 4px; }
              .profile-header p { margin: 0; color: #666; }
              pre { background: #f5f5f5; padding: 15px; border-radius: 5px; overflow-x: auto; }
          </style>
      </head>
      <body>
          <nav>
              <a href="${pageContext.request.contextPath}/">Home</a>
              <a href="${pageContext.request.contextPath}/logout" class="btn-logout">Logout</a>
          </nav>

          <div class="profile-header">
              <img src="${profile.get('picture').asString()}" alt="Profile picture"/>
              <div>
                  <h2>${profile.get('name').asString()}</h2>
                  <p>${profile.get('email').asString()}</p>
              </div>
          </div>

          <h3>Profile Details</h3>
          <pre><code>${profileJson}</code></pre>
      </body>
      </html>
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Lancez votre application" stepNumber={8}>
    Générez et exécutez l’application à l’aide du plugin Maven WildFly :

    ```shellscript theme={null}
    mvn clean wildfly:run
    ```

    Votre application devrait démarrer et afficher l’URL d’écoute :

    ```
    INFO  [org.jboss.as] WFLYSRV0025: WildFly started
    ```

    Ouvrez [http://localhost:8080](http://localhost:8080) dans votre navigateur. Cliquez sur le lien **Login** dans la barre de navigation. Vous serez redirigé vers la page de connexion d’Auth0. Après l’authentification, vous serez redirigé vers la [page de profil](http://localhost:8080/profile), où s’affichent les renseignements sur l’utilisateur et les claims JWT.

    <Info>
      L’exemple utilise JSP et a été testé avec le serveur d’applications [WildFly](https://wildfly.org/). Vous devrez peut-être adapter certaines étapes si vous utilisez un autre conteneur compatible avec Java EE 8.
    </Info>
  </Step>
</Steps>

<Check>
  **Point de vérification**

  Vous devriez maintenant avoir une application Java EE entièrement fonctionnelle, protégée par Auth0, qui s’exécute à l’adresse [http://localhost:8080](http://localhost:8080). Les utilisateurs peuvent ouvrir une session, consulter leur profil et fermer leur session.
</Check>

***

<div id="advanced-usage">
  ## Utilisation avancée
</div>

<Accordion title="Accéder aux informations du profil utilisateur">
  `Auth0JwtPrincipal` est accessible via `request.getUserPrincipal()` dans n’importe quel servlet. `ProfileServlet` montre comment accéder aux claims décodées de l’ID Token :

  ```java theme={null}
  Principal principal = request.getUserPrincipal();

  if (principal instanceof Auth0JwtPrincipal) {
      Auth0JwtPrincipal auth0JwtPrincipal = (Auth0JwtPrincipal) principal;
      DecodedJWT idToken = auth0JwtPrincipal.getIdToken();

      String name = idToken.getClaim("name").asString();
      String email = idToken.getClaim("email").asString();
      String picture = idToken.getClaim("picture").asString();
      String sub = idToken.getSubject();
  }
  ```

  Claims courantes disponibles dans l’ID Token :

  * `name` — nom complet affiché de l’utilisateur
  * `email` — adresse courriel de l’utilisateur
  * `picture` — URL de la photo de profil de l’utilisateur
  * `sub` — identifiant unique de l’utilisateur (id utilisateur Auth0)
</Accordion>

<Accordion title="Personnaliser les paramètres de connexion">
  Ajoutez des paramètres personnalisés à l’URL d’autorisation lors de sa création dans votre `LoginServlet` :

  ```java src/main/java/com/auth0/example/web/LoginServlet.java theme={null}
  String authURL = authenticationController
          .buildAuthorizeUrl(request, response, callbackUrl)
          .withScope(config.getScope())
          .withAudience("https://your-api.example.com")
          .withParameter("screen_hint", "signup")
          .withParameter("ui_locales", "fr")
          .build();
  ```

  Utilisez `.withAudience()` pour demander un jeton d’accès pour une API précise. Utilisez `.withParameter()` pour ajouter tout [paramètre d’autorisation](https://auth0.com/docs/api/authentication#authorize-application) supplémentaire pris en charge par Auth0.
</Accordion>

<Accordion title="Stocker les jetons pour les appels d’API">
  Pour accéder aux jetons bruts pour les appels d’API, modifiez `Auth0AuthenticationMechanism` afin de stocker les jetons dans la session :

  ```java src/main/java/com/auth0/example/security/Auth0AuthenticationMechanism.java theme={null}
  if (isCallbackRequest(httpServletRequest)) {
      try {
          Tokens tokens = authenticationController.handle(
                  httpServletRequest, httpServletResponse);

          httpServletRequest.getSession().setAttribute(
                  "accessToken", tokens.getAccessToken());

          Auth0JwtCredential auth0JwtCredential =
                  new Auth0JwtCredential(tokens.getIdToken());
          CredentialValidationResult result =
                  identityStoreHandler.validate(auth0JwtCredential);
          return httpMessageContext.notifyContainerAboutLogin(result);
      } catch (IdentityVerificationException e) {
          return httpMessageContext.responseUnauthorized();
      }
  }
  ```

  Récupérez ensuite le jeton d’accès lors de l’appel à une API protégée :

  ```java theme={null}
  String accessToken = (String) request.getSession().getAttribute("accessToken");
  URL url = new URL("https://your-api.example.com/data");
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setRequestProperty("Authorization", "Bearer " + accessToken);
  ```
</Accordion>

<Accordion title="Se connecter à une organisation">
  Configurez `AuthenticationController` avec un ID ou un nom d’organisation afin de restreindre la connexion à une [Organisation Auth0](https://auth0.com/docs/organizations) précise :

  ```java src/main/java/com/auth0/example/security/Auth0AuthenticationProvider.java theme={null}
  @Produces
  public AuthenticationController authenticationController(Auth0AuthenticationConfig config) {
      JwkProvider jwkProvider = new JwkProviderBuilder(config.getDomain()).build();
      return AuthenticationController.newBuilder(
                      config.getDomain(), config.getClientId(), config.getClientSecret())
              .withJwkProvider(jwkProvider)
              .withOrganization("org_YOUR_ORG_ID")
              .build();
  }
  ```

  Le SDK valide automatiquement la claim `org_id` ou `org_name` dans l’ID Token pour s’assurer qu’elle correspond à l’organisation configurée.
</Accordion>

***

<div id="additional-resources">
  ## Ressources supplémentaires
</div>

<CardGroup cols={2}>
  <Card title="SDK Java MVC d'Auth0" icon="github" href="https://github.com/auth0/auth0-java-mvc-common">
    Code source et suivi des problèmes
  </Card>

  <Card title="Référence de l’API (JavaDoc)" icon="code" href="https://javadoc.io/doc/com.auth0/mvc-auth-commons">
    Documentation détaillée de l’API
  </Card>

  <Card title="Forum communautaire" icon="comments" href="https://community.auth0.com/">
    Obtenez de l’aide auprès de la communauté Auth0
  </Card>

  <Card title="Exemple d’application Java EE" icon="github" href="https://github.com/auth0-samples/auth0-java-ee-sample/tree/master/01-Login">
    Exemple d’application complet sur GitHub
  </Card>
</CardGroup>

***

<div id="common-issues">
  ## Problèmes courants
</div>

<AccordionGroup>
  <Accordion title="Erreur de non-correspondance du state au callback">
    Si vous recevez une erreur `a0.invalid_state` après la connexion, le cookie de state est introuvable ou ne correspond pas au state renvoyé par Auth0.

    Vérifiez que :

    * L’URL de callback configurée dans l’Auth0 Dashboard correspond exactement à l’URL générée par votre application, y compris le numéro de port et le protocole.
    * Votre navigateur ne bloque pas les cookies tiers.
    * Aucun proxy inverse ni middleware ne supprime les en-têtes `Set-Cookie` des réponses.

    Assurez-vous d’utiliser la version à trois arguments de `buildAuthorizeUrl` et de `handle`, qui utilise le stockage du state dans des cookies :

    ```java theme={null}
    // Correct — utilise des cookies pour le state
    authenticationController.buildAuthorizeUrl(request, response, callbackUrl)
    authenticationController.handle(httpServletRequest, httpServletResponse)
    ```
  </Accordion>

  <Accordion title="Beans CDI non détectés">
    Si vous voyez des erreurs indiquant des échecs d’injection ou des beans introuvables, assurez-vous que :

    * Votre serveur d’applications prend en charge CDI 2.0 (qui fait partie de Java EE 8)
    * Toutes les classes de sécurité (`Auth0AuthenticationConfig`, `Auth0AuthenticationProvider`, `Auth0JwtIdentityStore`, `Auth0AuthenticationMechanism`) sont annotées avec `@ApplicationScoped`
    * `src/main/webapp/WEB-INF/jboss-web.xml` existe et que le domaine de sécurité `jaspitest` y est configuré

    ```xml src/main/webapp/WEB-INF/jboss-web.xml theme={null}
    <jboss-web>
        <security-domain>jaspitest</security-domain>
        <context-root>/</context-root>
    </jboss-web>
    ```

    Le domaine de sécurité `jaspitest` est requis pour que WildFly active l’intégration JASPIC (Java Authentication SPI for Containers) dont dépend l’API de sécurité Java EE 8.
  </Accordion>

  <Accordion title="Compatibilité du serveur d’applications">
    Ce quickstart utilise l’espace de noms `javax` (Java EE 8). Si vous utilisez un serveur qui a migré vers l’espace de noms `jakarta` (Jakarta EE 9+), comme WildFly 27+ ou Payara 6+, le code ne pourra ni se compiler ni s’exécuter.

    Utilisez un serveur compatible Java EE 8 :

    * WildFly 14 à 26
    * Payara 5
    * GlassFish 5
    * Open Liberty avec les fonctionnalités Java EE 8
  </Accordion>
</AccordionGroup>

***

<div id="sample-application">
  ## Application exemple
</div>

Une application Java EE exemple intégrée à Auth0 est offerte sur GitHub :

<Card title="Application Java EE exemple" icon="github" href="https://github.com/auth0-samples/auth0-java-ee-sample/tree/master/01-Login">
  Comprend des exemples de connexion, de déconnexion, de profil utilisateur et plus encore.
</Card>

Clonez et exécutez :

```bash theme={null}
git clone https://github.com/auth0-samples/auth0-java-ee-sample.git
cd auth0-java-ee-sample/01-Login
```

Mettez à jour les valeurs de configuration d’Auth0 dans `src/main/webapp/WEB-INF/web.xml`, puis exécutez :

```bash theme={null}
./mvnw clean wildfly:run
```

Accédez à [http://localhost:8080](http://localhost:8080) dans votre navigateur, puis cliquez sur **Login** pour faire un test.

***
