> ## 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.

# Java Spring Boot

> Agrega el inicio de sesión de Auth0 a una aplicación web de Spring Boot con Okta Spring Boot Starter.

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 />

<Note>
  **Requisitos previos:**

  * JDK 17+ ([descargar](https://adoptium.net/))
  * Maven 3.6+ o Gradle 7+ ([Maven](https://maven.apache.org/download.cgi) | [Gradle](https://gradle.org/install/))
  * Un IDE (se recomienda IntelliJ IDEA, Eclipse o VS Code)

  **Compatibilidad con versiones de Java:** Spring Boot 3.x+ y Okta Spring Boot Starter 3.x requieren Java 17 o superior.
</Note>

<div id="get-started">
  ## Primeros pasos
</div>

Esta guía de inicio rápido muestra cómo añadir el inicio de sesión de Auth0 a una aplicación web de Spring Boot. Crearás una aplicación web segura con inicio de sesión, cierre de sesión y una página de perfil protegida mediante Okta Spring Boot Starter, que configura automáticamente la compatibilidad con el inicio de sesión mediante OAuth2 de Spring Security.

<Steps>
  <Step title="Crear un proyecto nuevo" stepNumber={1}>
    Genera un proyecto de Spring Boot con las dependencias requeridas.

    <Tabs>
      <Tab title="Con Spring Initializr">
        ```bash theme={null}
        curl -L https://start.spring.io/starter.zip \
            -d dependencies=web,security,thymeleaf \
            -d javaVersion=17 \
            -d name=auth0-webapp \
            -d artifactId=auth0-webapp \
            -d packageName=com.auth0.example \
            -o auth0-webapp.zip

        mkdir auth0-webapp && unzip auth0-webapp.zip -d auth0-webapp && cd auth0-webapp
        ```
      </Tab>

      <Tab title="O créalo manualmente con Maven">
        ```bash theme={null}
        mvn archetype:generate \
            -DgroupId=com.auth0 \
            -DartifactId=auth0-webapp \
            -DarchetypeArtifactId=maven-archetype-quickstart \
            -DinteractiveMode=false

        cd auth0-webapp
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Añade el starter de Spring Boot de Okta" stepNumber={2}>
    Agrega la dependencia de Okta Spring Boot Starter a tu proyecto. Esto incluye la compatibilidad con el inicio de sesión OAuth2 de Spring Security, con configuración automática específica para Auth0/Okta.

    <Tabs>
      <Tab title="Maven (pom.xml)">
        ```xml theme={null}
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
        </dependency>
        <dependency>
            <groupId>com.okta.spring</groupId>
            <artifactId>okta-spring-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        ```
      </Tab>

      <Tab title="Gradle (build.gradle)">
        ```gradle theme={null}
        dependencies {
            implementation 'org.springframework.boot:spring-boot-starter-security'
            implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
            implementation 'org.springframework.boot:spring-boot-starter-web'
            implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
            implementation 'com.okta.spring:okta-spring-boot-starter:3.1.0'
            testImplementation 'org.springframework.boot:spring-boot-starter-test'
            testImplementation 'org.springframework.security:spring-security-test'
            testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurar Auth0" stepNumber={3}>
    Crea una aplicación web regular en tu tenant de Auth0 y agrega la configuración a tu proyecto.

    Puede hacerlo automáticamente ejecutando un comando de CLI o de forma manual desde el Dashboard:

    <Tabs>
      <Tab title="CLI">
        Ejecute el siguiente comando de shell en el directorio raíz del proyecto para crear una aplicación de Auth0 y actualizar el archivo `application.yml`:

        <Tabs>
          <Tab title="Mac/Linux">
            ```bash expandable theme={null}
            AUTH0_APP_NAME="My Spring Boot Webapp" && \
            brew tap auth0/auth0-cli && \
            brew install auth0 && \
            auth0 login --no-input && \
            auth0 apps create -n "${AUTH0_APP_NAME}" -t regular \
                --callbacks "http://localhost:3000/login/oauth2/code/okta" \
                --logout-urls "http://localhost:3000/" \
                --json > auth0-app-details.json && \
            DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && \
            CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && \
            CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && \
            mkdir -p src/main/resources && \
            printf 'server:\n  port: 3000\n\nokta:\n  oauth2:\n    issuer: https://%s/\n    client-id: %s\n    client-secret: %s\n' "$DOMAIN" "$CLIENT_ID" "$CLIENT_SECRET" > src/main/resources/application.yml && \
            rm auth0-app-details.json && \
            echo "✅ application.yml created with your Auth0 app details:" && \
            cat src/main/resources/application.yml
            ```
          </Tab>

          <Tab title="Windows (PowerShell)">
            ```powershell expandable theme={null}
            $AppName = "My Spring Boot Webapp"
            $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/auth0/auth0-cli/releases/latest"
            $latestVersion = $latestRelease.tag_name
            $version = $latestVersion -replace "^v"
            Invoke-WebRequest -Uri "https://github.com/auth0/auth0-cli/releases/download/${latestVersion}/auth0-cli_${version}_Windows_x86_64.zip" -OutFile ".\auth0.zip"
            Expand-Archive ".\auth0.zip" .\
            [System.Environment]::SetEnvironmentVariable('PATH', $Env:PATH + ";${pwd}")
            auth0 login --no-input
            auth0 apps create -n "$AppName" -t regular `
                --callbacks "http://localhost:3000/login/oauth2/code/okta" `
                --logout-urls "http://localhost:3000/" `
                --json | Set-Content -Path auth0-app-details.json
            $AppDetails = Get-Content -Raw auth0-app-details.json | ConvertFrom-Json
            $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name
            $ClientId = $AppDetails.client_id
            $ClientSecret = $AppDetails.client_secret
            New-Item -ItemType Directory -Force -Path "src\main\resources"
            @"
            server:
              port: 3000

            okta:
              oauth2:
                issuer: "https://$Domain/"
                client-id: "$ClientId"
                client-secret: "$ClientSecret"
            "@ | Set-Content "src\main\resources\application.yml"
            Remove-Item auth0-app-details.json
            Write-Output "✅ application.yml created with your Auth0 app details:"
            Get-Content "src\main\resources\application.yml"
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Panel">
        Antes de comenzar, agregue la configuración de Auth0 en su archivo `src/main/resources/application.yml`:

        ```yaml src/main/resources/application.yml expandable theme={null}
        server:
          port: 3000

        okta:
          oauth2:
            issuer: "https://YOUR_AUTH0_DOMAIN/"
            client-id: "YOUR_CLIENT_ID"
            client-secret: "YOUR_CLIENT_SECRET"
        ```

        1. Ve a [Auth0 Dashboard](https://manage.auth0.com) → **Applications** → **Applications**.
        2. Selecciona **Create Application**.
        3. Introduce un nombre (p. ej., "My Spring Boot Webapp") y selecciona **Regular Web Applications**.
        4. Selecciona **Create**.
        5. Ve a la pestaña **Application Settings** y configura:
           * **Allowed Callback URLs**: `http://localhost:3000/login/oauth2/code/okta`
           * **Allowed Logout URLs**: `http://localhost:3000/`
        6. Copia el **dominio**, el **ID de cliente** y el **Secreto del cliente** de la pestaña **Application Settings**.
        7. Sustituye los valores de marcador de posición en `application.yml`.

        <Info>
          La **URL de callback** debe coincidir exactamente. El inicio de sesión OAuth2 de Spring Security usa la ruta `/login/oauth2/code/okta` de forma predeterminada.

          El **emisor** debe incluir `https://` y una `/` al final. Usa solo el dominio y la región. Por ejemplo: `https://dev-abc123.us.auth0.com/`.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurar la autenticación" stepNumber={4}>
    Cree una configuración de seguridad que habilite el inicio de sesión con OAuth2 y administre el cierre de sesión en Auth0. Los usuarios no autenticados se redirigen automáticamente a la página de inicio de sesión de Auth0.

    ```java lines expandable theme={null}
    // src/main/java/com/auth0/example/SecurityConfig.java

    package com.auth0.example;

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.web.SecurityFilterChain;
    import org.springframework.security.web.authentication.logout.LogoutHandler;
    import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

    import java.io.IOException;

    import static org.springframework.security.config.Customizer.withDefaults;

    @Configuration
    public class SecurityConfig {

        @Value("${okta.oauth2.issuer}")
        private String issuer;
        @Value("${okta.oauth2.client-id}")
        private String clientId;

        @Bean
        public SecurityFilterChain configure(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests(authorize -> authorize
                    .requestMatchers("/", "/images/**").permitAll()
                    .anyRequest().authenticated()
                )
                .oauth2Login(withDefaults())
                .logout(logout -> logout
                    .addLogoutHandler(logoutHandler()));
            return http.build();
        }

        private LogoutHandler logoutHandler() {
            return (request, response, authentication) -> {
                try {
                    String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
                    response.sendRedirect(issuer + "v2/logout?client_id=" + clientId + "&returnTo=" + baseUrl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            };
        }
    }
    ```
  </Step>

  <Step title="Crear controladores y vistas" stepNumber={5}>
    Crea los controladores y las plantillas de Thymeleaf para las páginas de inicio y perfil.

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

      import org.springframework.security.core.annotation.AuthenticationPrincipal;
      import org.springframework.security.oauth2.core.oidc.user.OidcUser;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.GetMapping;

      @Controller
      public class HomeController {

          @GetMapping("/")
          public String home(Model model, @AuthenticationPrincipal OidcUser principal) {
              if (principal != null) {
                  model.addAttribute("profile", principal.getClaims());
              }
              return "index";
          }
      }
      ```

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

      import com.fasterxml.jackson.core.JsonProcessingException;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
      import org.springframework.security.core.annotation.AuthenticationPrincipal;
      import org.springframework.security.oauth2.core.oidc.user.OidcUser;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.GetMapping;

      import java.util.Map;

      @Controller
      public class ProfileController {

          private final static ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

          @GetMapping("/profile")
          public String profile(Model model, @AuthenticationPrincipal OidcUser oidcUser) {
              model.addAttribute("profile", oidcUser.getClaims());
              model.addAttribute("profileJson", claimsToJson(oidcUser.getClaims()));
              return "profile";
          }

          private String claimsToJson(Map<String, Object> claims) {
              try {
                  return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(claims);
              } catch (JsonProcessingException jpe) {
                  return "Error al analizar las claims como JSON.";
              }
          }
      }
      ```

      ```html src/main/resources/templates/index.html expandable lines theme={null}
      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
      <head>
          <meta charset="UTF-8">
          <title>Inicio de sesión de Auth0 con Spring Boot</title>
      </head>
      <body>
          <h1>Ejemplo de inicio de sesión de Auth0 con Spring Boot</h1>

          <div sec:authorize="!isAuthenticated()">
              <p>No has iniciado sesión.</p>
              <a href="/oauth2/authorization/okta">Iniciar sesión</a>
          </div>

          <div sec:authorize="isAuthenticated()">
              <p>¡Bienvenido, <span sec:authentication="name">usuario</span>!</p>
              <ul>
                  <li><a href="/profile">Ver perfil</a></li>
                  <li>
                      <form th:action="@{/logout}" method="post" style="display:inline;">
                          <button type="submit">Cerrar sesión</button>
                      </form>
                  </li>
              </ul>
          </div>
      </body>
      </html>
      ```

      ```html src/main/resources/templates/profile.html expandable lines theme={null}
      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title>Perfil del usuario</title>
      </head>
      <body>
          <h1>Perfil del usuario</h1>
          <a href="/">Inicio</a>

          <div th:if="${profile}">
              <img th:if="${profile['picture']}" th:src="${profile['picture']}" width="64" height="64" alt="Foto de perfil" />
              <h2 th:text="${profile['name']}">Nombre</h2>
              <p th:text="${profile['email']}">Correo electrónico</p>
          </div>

          <h3>Todas las claims</h3>
          <pre th:text="${profileJson}">Claims JSON</pre>

          <form th:action="@{/logout}" method="post">
              <button type="submit">Cerrar sesión</button>
          </form>
      </body>
      </html>
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Ejecuta la aplicación" stepNumber={6}>
    Inicie la aplicación con el wrapper de Maven o Gradle.

    <Tabs>
      <Tab title="Maven">
        ```bash theme={null}
        ./mvnw spring-boot:run
        ```
      </Tab>

      <Tab title="Gradle">
        ```bash theme={null}
        ./gradlew bootRun
        ```
      </Tab>
    </Tabs>

    La aplicación ya se está ejecutando en `http://localhost:3000`. Vaya a `http://localhost:3000/profile` para iniciar el flujo de inicio de sesión de Auth0.
  </Step>
</Steps>

<Check>
  Ahora debería tener una aplicación web de Spring Boot completamente funcional con el inicio de sesión de Auth0 ejecutándose en [localhost](http://localhost:3000/). La página de inicio es pública y, al navegar a `/profile`, los usuarios no autenticados son redirigidos a la página de inicio de sesión de Auth0.
</Check>

***

<div id="advanced-usage">
  ## Uso avanzado
</div>

<Accordion title="Acceso a los claims del perfil de usuario">
  El parámetro `@AuthenticationPrincipal OidcUser` le da acceso a todos los claims del ID Token. Use `getClaims()` para recuperar el conjunto completo o métodos getter individuales para claims específicos.

  ```java theme={null}
  @GetMapping("/profile")
  public String profile(Model model, @AuthenticationPrincipal OidcUser oidcUser) {
      model.addAttribute("name", oidcUser.getFullName());
      model.addAttribute("email", oidcUser.getEmail());
      model.addAttribute("picture", oidcUser.getPicture());
      model.addAttribute("sub", oidcUser.getSubject());
      model.addAttribute("allClaims", oidcUser.getClaims());
      return "profile";
  }
  ```
</Accordion>

<Accordion title="Control de acceso basado en roles">
  Puede restringir el acceso a las páginas en función de los roles de Auth0. Primero, agregue roles al ID Token mediante una Action de Auth0 y, después, use `hasAuthority()` en su configuración de seguridad.

  ### Agregar roles a los tokens

  1. Vaya a [Auth0 Dashboard](https://manage.auth0.com) → **Actions** → **Flows** → **Login**.
  2. Cree una Action personalizada que agregue roles como un claim personalizado al ID Token:

  ```javascript theme={null}
  exports.onExecutePostLogin = async (event, api) => {
    const namespace = "https://my-app.example.com";
    if (event.authorization) {
      api.idToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
    }
  };
  ```

  ### Configurar la autorización

  Actualice su `SecurityConfig` para requerir roles específicos en los endpoints:

  ```java expandable theme={null}
  @Bean
  public SecurityFilterChain configure(HttpSecurity http) throws Exception {
      http
          .authorizeHttpRequests(authorize -> authorize
              .requestMatchers("/", "/images/**").permitAll()
              .requestMatchers("/admin/**").hasAuthority("ROLE_admin")
              .anyRequest().authenticated()
          )
          .oauth2Login(withDefaults())
          .logout(logout -> logout
              .addLogoutHandler(logoutHandler()));
      return http.build();
  }
  ```
</Accordion>

<Accordion title="Asignación personalizada de autoridades">
  El starter de Okta admite la asignación personalizada de autoridades mediante la interfaz `AuthoritiesProvider`. Registre un bean para agregar objetos `GrantedAuthority` personalizados en función de los atributos del usuario o de fuentes de datos externas.

  ```java expandable theme={null}
  package com.auth0.example;

  import com.okta.spring.boot.oauth.AuthoritiesProvider;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;

  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;

  @Configuration
  public class AuthoritiesConfig {

      @Bean
      AuthoritiesProvider customAuthoritiesProvider() {
          return (user, userRequest) -> {
              Set<GrantedAuthority> authorities = new HashSet<>();

              // Asigna el claim de roles personalizado a autoridades de Spring Security
              Object roles = user.getAttribute("https://my-app.example.com/roles");
              if (roles instanceof List<?> roleList) {
                  roleList.forEach(role ->
                      authorities.add(new SimpleGrantedAuthority("ROLE_" + role))
                  );
              }

              return authorities;
          };
      }
  }
  ```
</Accordion>

***

<div id="common-issues">
  ## Problemas comunes
</div>

<AccordionGroup>
  <Accordion title="Error al redirigir al inicio de sesión: URL de callback no válida">
    Después de seleccionar **Iniciar sesión**, Auth0 muestra un error porque la URL de callback no coincide.

    Las **Allowed Callback URLs** de tu aplicación de Auth0 deben coincidir exactamente con la URL de callback que usa Spring Security. La URL predeterminada es `http://localhost:3000/login/oauth2/code/okta`.

    1. Ve a [Auth0 Dashboard](https://manage.auth0.com) → **Applications** → Tu aplicación → **Settings**.
    2. En **Allowed Callback URLs**, agrega: `http://localhost:3000/login/oauth2/code/okta`.
    3. Selecciona **Save Changes**.
  </Accordion>

  <Accordion title="Issuer no válido al iniciar">
    La aplicación no se inicia o el inicio de sesión falla porque el issuer no coincide.

    `okta.oauth2.issuer` debe ser la URL completa del inquilino de Auth0, incluidos `https://` y la `/` final.

    ```yaml theme={null}
    # ❌ INCORRECTO: falta https:// o la barra final
    okta:
      oauth2:
        issuer: "dev-abc123.us.auth0.com"

    # ✅ CORRECTO: URL completa con barra final
    okta:
      oauth2:
        issuer: "https://dev-abc123.us.auth0.com/"
    ```
  </Accordion>

  <Accordion title="Error de detección de OIDC al iniciar">
    La aplicación no se inicia y muestra un error de conexión al obtener `/.well-known/openid-configuration`.

    Okta Spring Boot Starter obtiene el documento de detección de OpenID Connect desde la URL del issuer al iniciar la aplicación. Verifica que la URL del issuer sea correcta y que se pueda acceder a ella desde tu red. Si estás detrás de un firewall corporativo, configura el proxy:

    ```yaml theme={null}
    okta:
      oauth2:
        issuer: "https://dev-abc123.us.auth0.com/"
        proxy:
          host: "proxy.example.com"
          port: 8080
    ```
  </Accordion>

  <Accordion title="No se encuentran los valores de configuración">
    La aplicación se inicia, pero el inicio de sesión falla porque no se están leyendo las propiedades de configuración.

    Asegúrate de que `application.yml` use la sangría YAML correcta dentro del espacio de nombres `okta.oauth2`:

    ```yaml theme={null}
    # ❌ INCORRECTO: estructura plana, no anidada
    okta.oauth2.issuer: "https://dev-abc123.us.auth0.com/"

    # ✅ CORRECTO: YAML correctamente anidado
    okta:
      oauth2:
        issuer: "https://dev-abc123.us.auth0.com/"
        client-id: "YOUR_CLIENT_ID"
        client-secret: "YOUR_CLIENT_SECRET"
    ```
  </Accordion>

  <Accordion title="Cerrar sesión no borra la sesión de Auth0">
    Después de seleccionar **Cerrar sesión**, el usuario vuelve a iniciar sesión de inmediato sin ver la página de inicio de sesión de Auth0.

    Asegúrate de que `SecurityConfig` incluya el `LogoutHandler` personalizado que redirige al endpoint `/v2/logout` de Auth0. Verifica también que **Allowed Logout URLs** en la configuración de tu aplicación de Auth0 incluya `http://localhost:3000/`.
  </Accordion>
</AccordionGroup>

***

<div id="additional-resources">
  ## Recursos adicionales
</div>

<CardGroup cols={3}>
  <Card title="Documentación del SDK" icon="book" href="https://github.com/okta/okta-spring-boot">
    Documentación completa del SDK, código fuente y notas de la versión
  </Card>

  <Card title="Documentación de Auth0" icon="file-lines" href="https://auth0.com/docs">
    Documentación oficial de Auth0 para aplicaciones de Spring Boot
  </Card>

  <Card title="Referencia de Spring Security" icon="shield" href="https://docs.spring.io/spring-security/reference/servlet/oauth2/login.html">
    Documentación de inicio de sesión con OAuth2 en Spring Security
  </Card>

  <Card title="Referencia de configuración" icon="gear" href="https://github.com/okta/okta-spring-boot#configuration-reference">
    Todas las propiedades de configuración disponibles de okta.oauth2.\*
  </Card>

  <Card title="Auth0 Dashboard" icon="browser" href="https://manage.auth0.com/">
    Administra tus API y aplicaciones en Auth0
  </Card>

  <Card title="Foro de la comunidad" icon="comments" href="https://community.auth0.com/">
    Obtén ayuda de la comunidad de Auth0
  </Card>
</CardGroup>

***

<div id="sample-application">
  ## Aplicación de ejemplo
</div>

En el repositorio de ejemplos de Auth0 hay disponible una aplicación de ejemplo completa que muestra cómo iniciar sesión, ver el perfil y cerrar sesión con Auth0.

<Card title="Ejemplo de inicio de sesión MVC" icon="github" href="https://github.com/auth0-samples/auth0-spring-boot-login-samples/tree/master/mvc-login">
  Incluye inicio de sesión, cierre de sesión y una página de perfil con integración de Auth0 OAuth2
</Card>

Clona y ejecuta:

```bash theme={null}
git clone https://github.com/auth0-samples/auth0-spring-boot-login-samples.git
cd auth0-spring-boot-login-samples/mvc-login

# Actualiza src/main/resources/application.yml con tu configuración de Auth0
# Luego ejecuta:
./gradlew bootRun
```

Abre `http://localhost:3000` en tu navegador y selecciona el enlace **Login** para probar el flujo de inicio de sesión con Auth0.
