Incorporación de inicio de sesión con Azure Active Directory B2C a una aplicación web de Spring
En este artículo se muestra cómo crear una aplicación java con funcionalidad de inicio de sesión mediante Spring Initializr con spring Boot Starter para Microsoft Entra ID.
En este tutorial, aprenderá a:
- Creación de una aplicación Java mediante Spring Initializr
- Configuración de Azure Active Directory B2C
- Protección de la aplicación con clases y anotaciones de Spring Boot
- Compilación y prueba de la aplicación Java
microsoft Entra ID es la solución de identidad empresarial de escala de nube de Microsoft. Azure Active Directory B2C complementa el conjunto de características de Microsoft Entra ID, lo que le permite administrar el acceso de cliente, consumidor y ciudadano a las aplicaciones de negocio a consumidor (B2C).
Prerrequisitos
- Una suscripción de Azure. Si aún no tiene una, cree una cuenta gratuita antes de comenzar.
- Un kit de desarrollo de Java (JDK) compatible. Para más información sobre los JDK disponibles para su uso al desarrollar en Azure, consulte compatibilidad con Java en Azure y Azure Stack.
- apache Maven, versión 3.0 o posterior.
Importante
Se requiere Spring Boot versión 2.5 o posterior para completar los pasos descritos en este artículo.
Creación de una aplicación con Spring Initializr
Explore en https://start.spring.io/.
Rellene los valores según esta guía. Las etiquetas y el diseño pueden diferir de la imagen que se muestra aquí.
- En Project, seleccione Maven Project.
- En Lenguaje, seleccione Java.
- En Spring Boot, seleccione 2.7.11.
- En Grupo, Artefacto y Nombre escriba el mismo valor, usando una cadena descriptiva corta. La interfaz de usuario puede rellenar automáticamente algunos de estos campos a medida que escribe.
- En el panel de dependencias , seleccione Agregar dependencias. Use la interfaz de usuario para agregar dependencias en Spring Web y Spring Security.
Nota
Spring Security 5.5.1, 5.4.7, 5.3.10 y 5.2.11 se han publicado para abordar el siguiente informe CVE CVE-2021-22119: Ataque por denegación de servicio con spring-security-oauth2-client. Si usa la versión anterior, actualícela.
Seleccione Generar proyecto y descargue el proyecto en una ruta de acceso del equipo local. Mueva el archivo descargado a un directorio denominado después del proyecto y descomprima el archivo. El diseño del archivo debe tener un aspecto similar al siguiente, con el valor especificado para Group en lugar de
yourProject
.. ├── HELP.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main │ ├── java │ │ └── yourProject │ │ └── yourProject │ │ └── YourProjectApplication.java │ └── resources │ ├── application.properties │ ├── static │ └── templates └── test └── java └── yourProject └── yourProject └── YourProjectApplicationTests.java
Creación e inicialización de una instancia de Microsoft Entra
Creación de la instancia de Active Directory
Inicie sesión en https://portal.azure.com.
Seleccione Crear un recurso. Busque Azure Active Directory B2C.
Seleccione Crear.
Seleccione Crear un nuevo inquilino de Azure AD B2C.
En Nombre de la organización y Nombre de dominio inicial, proporcione los valores correspondientes y, a continuación, seleccione Crear.
Una vez completada la creación de Active Directory, seleccione la cuenta en la esquina superior derecha, seleccione Cambiar directorioy, a continuación, seleccione el directorio creado. Se le redirigirá a la nueva página principal del inquilino. A continuación, busque
b2c
y seleccione Azure AD B2C.
Añade un registro de aplicación para tu app de Spring Boot
En el panel Administrar, seleccione Registros de aplicaciones y, a continuación, seleccione Nuevo registro.
En el campo Nombre, escriba el nombre de la aplicación y seleccione Registrar.
De nuevo en el panel Administrar, seleccione Registros de aplicacionesy, a continuación, seleccione el nombre de la aplicación que creó.
Seleccione Autenticación y, a continuación, Agregar una plataforma y, después, Web. Establezca los URI de redireccionamiento en
http://localhost:8080/login/oauth2/code/
y, a continuación, seleccione Configurar.
Añadir secretos de aplicación para tu aplicación
Seleccione Certificados y secretos y, después, Nuevos secretos de cliente. Escriba la descripción del secreto y seleccione Agregar. Después de crear el secreto, seleccione el icono de copia situado junto al valor secreto para copiar el valor para usarlo más adelante en este artículo.
Nota
Si sale de la sección Certificados y secretos y luego vuelve, no podrá ver el valor del secreto. En ese caso, debe crear otro secreto y copiarlo para su uso futuro. Algunas veces, el valor del secreto generado puede contener caracteres que son problemáticos para su inclusión en el archivo application.yml, como la barra diagonal inversa o el acento grave. En ese caso, descarte ese secreto y genere otro.
Agregar flujo de usuario
Vaya a la página principal del inquilino. En la sección Directivas del panel izquierdo, seleccione Flujos de usuarioy, a continuación, seleccione Nuevo flujo de usuario.
Ahora dejará este tutorial, ejecutará otro tutorial y volverá a este tutorial cuando haya terminado. Estas son algunas cosas que debe tener en cuenta al ir al otro tutorial.
- Comience en el paso que le pide que seleccione Nuevo flujo de usuario.
- Cuando este tutorial hace referencia a
webapp1
, use el valor especificado para Grupo en su lugar. - Al seleccionar las notificaciones que se van a devolver desde los flujos, asegúrese de que Nombre para mostrar esté seleccionado. Sin esta notificación, la aplicación que se está generando en este tutorial no funcionará.
- Cuando se le pide que ejecute los flujos de usuario, la dirección URL de redireccionamiento que especificó anteriormente aún no está activa. Todavía puede ejecutar los flujos, pero el redireccionamiento no se completará correctamente. Esto es lo esperado.
- Cuando llegue a "Pasos siguientes", vuelva a este tutorial.
Siga todos los pasos descritos en Tutorial: Creación de flujos de usuario en Azure Active Directory B2C para crear flujos de usuario para "registro e inicio de sesión", "edición de perfiles" y "restablecimiento de contraseña".
Azure AD B2C admite cuentas locales, así como proveedores de identidades sociales. Para obtener un ejemplo de creación de un proveedor de identidades de GitHub, consulte Configuración del registro e inicio de sesión con una cuenta de GitHub mediante Azure Active Directory B2C.
Configuración y compilación de la aplicación
Ahora que ha creado la instancia de Azure AD B2C y algunos flujos de usuario, conectará la aplicación spring a la instancia de Azure AD B2C.
Desde la línea de comandos, use el comando "cd" para ir al directorio donde descomprimió el archivo .zip que descargó desde Spring Initializr.
Vaya a la carpeta primaria del proyecto y abra el archivo de proyecto pom.xml Maven en un editor de texto.
Agregue las dependencias para la seguridad OAuth2 de Spring a pom.xml:
<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-active-directory-b2c</artifactId> <version>See Below</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>See Below</version> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> <version>See Below</version> </dependency>
Para
spring-cloud-azure-starter-active-directory-b2c
, actualice a la versión más reciente disponible. Puede usar mvnrepository.com para buscar esto.Para
spring-boot-starter-thymeleaf
, utilice la versión correspondiente a la de Spring Boot que seleccionó anteriormente; por ejemplo,2.3.4.RELEASE
.Para
thymeleaf-extras-springsecurity5
, use la versión más reciente disponible. Puede usar mvnrepository.com para buscar esto. Hasta el momento de escribir esto, la versión más reciente es3.0.4.RELEASE
.Guarde y cierre el archivo pom.xml.
- Compruebe que las dependencias son correctas mediante la ejecución de
mvn -DskipTests clean install
. Si no veBUILD SUCCESS
, subsane este problema antes de continuar.
- Compruebe que las dependencias son correctas mediante la ejecución de
Vaya a la carpeta src/main/resources del proyecto y cree un archivo application.yml en un editor de texto.
Especifique la configuración del registro de la aplicación con los valores que creó anteriormente; por ejemplo:
spring: cloud: azure: active-directory: b2c: enabled: true base-uri: https://<your-tenant-initial-domain-name>.b2clogin.com/<your-tenant-initial-domain-name>.onmicrosoft.com/ credential: client-id: <your-application-ID> client-secret: '<secret-value>' login-flow: sign-up-or-sign-in logout-success-url: <your-logout-success-URL> user-flows: sign-up-or-sign-in: <your-sign-up-or-sign-in-user-flow-name> profile-edit: <your-profile-edit-user-flow-name> password-reset: <your-password-reset-user-flow-name> user-name-attribute-name: <your-user-name-attribute-name>
Observe que el valor de
client-secret
se incluye entre comillas simples. Esto es necesario porque el valor de<secret-value>
casi seguramente contendrá algunos caracteres que requieren estar entre comillas simples cuando estén presentes en YAML.Nota
A partir de este artículo, la lista completa de valores de Active Directory B2C Spring Integration que están disponibles para su uso en application.yml es la siguiente:
spring: cloud: azure: active-directory: b2c: enabled: true base-uri: credential: client-id: client-secret: login-flow: logout-success-url: user-flows: sign-up-or-sign-in: profile-edit: # optional password-reset: # optional user-name-attribute-name:
El archivo application.yml está disponible en el ejemplo "spring-cloud-azure-starter-active-directory-b2c": aad-b2c-web-application en GitHub.
Guarde y cierre el archivo application.yml.
Cree una carpeta llamada controller en src/main/java/<yourGroupId>/<yourGroupId> y reemplace
<yourGroupId>
por el valor que especificó en Grupo.Cree un nuevo archivo java denominado WebController.java en la carpeta controlador y ábralo en un editor de texto.
Escriba el código siguiente, cambie
yourGroupId
adecuadamente y, a continuación, guarde y cierre el archivo:package yourGroupId.yourGroupId.controller; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class WebController { private void initializeModel(Model model, OAuth2AuthenticationToken token) { if (token != null) { final OAuth2User user = token.getPrincipal(); model.addAttribute("grant_type", user.getAuthorities()); model.addAllAttributes(user.getAttributes()); } } @GetMapping(value = "/") public String index(Model model, OAuth2AuthenticationToken token) { initializeModel(model, token); return "home"; } @GetMapping(value = "/greeting") public String greeting(Model model, OAuth2AuthenticationToken token) { initializeModel(model, token); return "greeting"; } @GetMapping(value = "/home") public String home(Model model, OAuth2AuthenticationToken token) { initializeModel(model, token); return "home"; } }
Dado que cada método del controlador llama a
initializeModel()
y ese método llama amodel.addAllAttributes(user.getAttributes());
, cualquier página HTML de src/main/resources/templates puede acceder a cualquiera de esos atributos, como${name}
,${grant_type}
o${auth_time}
. De hecho, los valores devueltos poruser.getAttributes()
son las notificaciones deid_token
para la autenticación. La lista completa de notificaciones disponibles se muestra en Tokens de identificador de la plataforma de identidad de Microsoft.Cree una carpeta denominada de seguridad en src/main/java/<yourGroupId>/<yourGroupId>, reemplazando
yourGroupId
por el valor especificado para Group.Cree un nuevo archivo java denominado
WebSecurityConfiguration.java en la carpeta de seguridad dey ábralo en un editor de texto. Escriba el código siguiente, cambie
yourGroupId
adecuadamente y, a continuación, guarde y cierre el archivo:package yourGroupId.yourGroupId.security; import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cOidcLoginConfigurer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { private final AadB2cOidcLoginConfigurer configurer; public WebSecurityConfiguration(AadB2cOidcLoginConfigurer configurer) { this.configurer = configurer; } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .apply(configurer) ; } }
Copie el archivo home.html del ejemplo spring-cloud-azure-starter-active-directory-b2c: aad-b2c-web-application a src/main/resources/templates y reemplace
${your-profile-edit-user-flow}
y${your-password-reset-user-flow}
con los nombres de los flujos de usuario que creó anteriormente.
Compilación y prueba de la aplicación
Abra un terminal de comandos y cambie al directorio de la carpeta donde se encuentra el archivo pom.xml de su aplicación.
Compile la aplicación de Spring Boot con Maven y ejecútelo; por ejemplo:
Nota
Es extremadamente importante que la hora según el reloj del sistema donde se ejecuta la aplicación local de Spring Boot sea precisa. Hay muy poca tolerancia a la asimetría del reloj al usar OAuth 2.0. Incluso tres minutos de inexactitud pueden provocar un error en el inicio de sesión con un error similar a
[invalid_id_token] An error occurred while attempting to decode the Jwt: Jwt used before 2020-05-19T18:52:10Z
. En el momento de redactar este documento, time.gov indica la diferencia de su reloj respecto de la hora real. La aplicación se ejecutó correctamente con una asimetría de +0,019 segundos.mvn -DskipTests clean package mvn -DskipTests spring-boot:run
Una vez que Maven compila e inicia la aplicación, abra
http://localhost:8080/
en un explorador web; debe redirigirse a la página de inicio de sesión.Seleccione el vínculo con texto relacionado con el inicio de sesión. Debe ser redirigido a Azure AD B2C para iniciar el proceso de autenticación.
Una vez que haya iniciado sesión correctamente, debería ver el
home page
de ejemplo desde el explorador.
Solución de problemas
En las secciones siguientes se describe cómo resolver algunos problemas que podría surgir.
Falta el nombre de atributo en los atributos
Al ejecutar el ejemplo, puede obtener una excepción con el mensaje Missing attribute 'name' in attributes
. El registro de esta excepción tendrá un aspecto similar al siguiente resultado:
java.lang.IllegalArgumentException: Missing attribute 'name' in attributes
at org.springframework.security.oauth2.core.user.DefaultOAuth2User.<init>(DefaultOAuth2User.java:67) ~[spring-security-oauth2-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser.<init>(DefaultOidcUser.java:89) ~[spring-security-oauth2-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:144) ~[spring-security-oauth2-client-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:63) ~[spring-security-oauth2-client-5.3.6.RELEASE.jar:5.3.6.RELEASE]
Si recibe este error, compruebe el flujo de trabajo de usuario que creó en Tutorial: Creación de flujos de usuario en Azure Active Directory B2C. Cuando cree el flujo de trabajo de usuario, en Atributos y notificaciones de usuario, asegúrese de elegir atributos y notificaciones en Nombre para mostrar. Además, asegúrese de configurar correctamente user-name-attribute-name
en el archivo application.yml.
Inicio de sesión con bucles en el punto de conexión de B2C
Este problema es más probable que se deba a cookies contaminantes para localhost
. Limpie las cookies para localhost
e inténtelo de nuevo.
Resumen
En este tutorial, ha creado una nueva aplicación web de Java mediante el inicio de Azure Active Directory B2C, ha configurado un nuevo inquilino de Azure AD B2C y ha registrado una nueva aplicación en ella y, a continuación, ha configurado la aplicación para que use las anotaciones y clases de Spring para proteger la aplicación web.
Limpieza de recursos
Cuando ya no sea necesario, use el Azure Portal para eliminar los recursos creados en este artículo para evitar cargos inesperados.
Pasos siguientes
Para más información sobre Spring y Azure, continúe con el Centro de documentación de Spring en Azure.