Ir al contenido principal

Integración de WSO2 Identity Server con Spring Boot y Spring Security – Protocolo SAML

La presente guía tiene como objetivo ejemplificar la integración que se puede dar entre WSO2 Identity Server y el framework para el desarrollo de aplicaciones Spring para lograr la autentificación de los usuarios utilizando el protocolo SAML2.

Para ello se seguirá el siguiente índice:

  1. Qué es SAML2
  2. Prerrequisitos para desarrollar un proyecto en Spring
  3. Glosario de términos
  4. Creación de proyecto en Spring
    1. Antes de iniciar la creación de proyecto
    2. Creación de proyecto en Spring Boot
    3. Configuración de Spring Boot del proyecto
    4. Configuración de Spring Security del proyecto
    5. Explicación código
    6. Creación de clase Service Model
    7. Creación de clase Controller
  5. Creación de Service Provider en WSO2
    1. Pruebas – Creación de un usuario de prueba
  6. Conclusiones

1. Qué es SAML2

El protocolo SAML2 (Security Assertion Markup Language 2.0), es una versión del estándar SAML para intercambiar identidades de autenticación y autorización entre dominios de seguridad  basado en XML que utiliza tokens de seguridad que contienen aserciones e incluyen información del usuario.

Esto permite el inicio de sesión único (SSO) entre dominios basado en la web, ayudando a reducir la sobrecarga administrativa de distribuir múltiples tokens de autenticación al usuario.

2. Prerrequisitos para desarrollar un proyecto en Spring

Para el desarrollo de un proyecto en Spring se deben cumplir con los siguientes requisitos:

  • java 1.8  o superior
  • maven
  • IDE de desarrollo como sts, eclipse u otro.

Para la configuración de SAMl con WSO2 Identity Server, se debe contar con la versión 5.7 o superior.

3. Glosario de términos

Para entender el proceso de creación de un proyecto en Spring, es fundamental tener claro algunos conceptos que os explicamos a continuación: 

Palabra Descripción
SAML Secure Assertion Markup Language (SAML) es un documento XML firmado digitalmente que incluye información sobre los sistemas de usuario, origen y destino que están destinados a utilizar este documento XML y otra información para validar la firma XML.
IdP Proveedor de identidad (IDP) es un sistema que puede identificar al usuario y emitir el documento SAML firmado.
SP El proveedor de servicios (SP) es un sistema que recibe SAML XML
Metadata Es un documento XML que contiene información sobre el proveedor de identidad y el proveedor de servicios. El proveedor de identidad emite XML de metadatos cuando un proveedor de servicios registra la aplicación.
Single Sign-on (SSO) SSO: Es un proceso de autenticación que permite a los usuarios utilizar credenciales únicas en varias aplicaciones dentro de una organización.

4. Creación de proyecto en Spring

4.1 Antes de iniciar la creación de proyecto

Spring proporciona a continuación dos artefactos para manejar SAML 2.0.

  • spring-security-saml2-core: SAML2 core es una extensión de Spring Security para admitir el procesamiento SAML básico para el inicio de sesión único.
  • spring-security-saml-dsl-core: saml dsl se usa junto con SAML 2 core, que contiene la configuración básica para la asignación de solicitudes, el filtro y la configuración del proveedor de autenticación.

Podemos usar SAML2 core solo, pero necesitamos configurar el mapeo de solicitudes, los filtros y la autenticación, el contexto SAML y muchos otros detalles que son comunes para la mayoría de las aplicaciones. Para evitar todo esto, solo usamos, saml dsl. spring-security-saml-dsl-core, ya que contiene los siguientes detalles de asignación de solicitudes configurados de forma predeterminada:

    • /saml/metadata: esta asignación se utiliza para mostrar y leer el archivo de metadatos.
    • /saml/login: responsable de generar la solicitud de inicio de sesión y redirigir a la página IDP para iniciar sesión.
    • /saml/logout: se utiliza para cerrar la sesión y borrar la sesión global o local.
    • /saml/SSO: esta es la URL de devolución de llamada exitosa e IDP usa esta asignación de solicitud para publicar el SAML.

 4.2 Creación de proyecto en Spring Boot

Para iniciar se debe crear un arquetipo de proyecto, se puede crear dicho arquetipo en la siguiente url https://start.spring.io/ en la cual se debe ingresar la información del proyecto como se muestra a continuación.

crear arquetipo de proyecto

Nota: también se puede cambiar la herramienta con la que se puede construir el proyecto (Maven o Gradle), el lenguaje (Java, Kotlin, Groovy) y la versión de Spring Boot.

Posteriormente se debe dar clic en el botón de ADD DEPENDENCIES, para agregar dependencias necesarias, las cuales son:

  • Spring Boot DevTools
  • Spring Web
  • Spring Security
  • Thymeleaf

Para finalizar se debe dar clic en el botón de GENERATE, el cual generará el proyecto con la información ingresada, posteriormente se pedirá que se descargue el proyecto.

4.3 Configuración de Spring Boot del proyecto

Una vez descargado el proyecto, se procederá a descomprimir el proyecto y colocarlo en una ruta de la preferencia de la persona, para así importar el proyecto en el IDE.

Posteriormente a importar el proyecto, se procederá a agregar 2 dependencias más en el pom las cuales son: spring-security-saml2-core y spring-security-saml-dsl-core.

<!-- SAML2 Dependencies -->
    <dependency>
    <groupId>org.springframework.security.extensions</groupId>
    <artifactId>spring-security-saml2-core</artifactId>
    <version>1.0.3.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.security.extensions</groupId>
    <artifactId>spring-security-saml-dsl-core</artifactId>
    <version>1.0.5.RELEASE</version>
    </dependency>
<!-- SAML2 Dependencies -->

A continuación se renombrara el archivo application.properties por el de application.yml el cual se encuentra en la ruta src/main/resources/, donde se debe agregar las variables que se utilizarán en la configuración de de seguridad en la clase ConfigSecurity

saml2:
  metadata-path: classpath:static/saml2_metadata.xml
  sp:
    protocol: http
    host: localhost:8080
    path: /
    key-store:
      file: classpath:static/keystore.jks
      alias: saml2cert
      password: cky4159

Donde:

Parámetro Valor Descripción
saml2.metadata-path classpath:static/saml2_metadata.xml Archivo donde se encuentra la metadata del IdP el cual autenticara y autorizara al usuario.
saml2.sp.protocol http Protocolo por el cual se realizará la comunicación, puede ser también https.
saml2.sp.host localhost:8080 Host al que se emite la solicitud GET al servicio SSO.
saml2.sp.path / Si en dado cuenta con un path que no se por default.
saml2.sp.key-store.file classpath:static/keystore.jks JKS con los certificados de seguridad, ya sea certificados de autorización o certificados de clave pública, más las claves privadas correspondientes, que se utilizan, por ejemplo, en el cifrado SSL.
saml2.sp.key-store.alias saml2cert Alias para la llave.
saml2.sp.key-store.password cky4159 Contraseña utilizada para el almacén de claves.

Una vez realizado el paso anterior se debe crear la carpeta static en la ruta src/main/resources/ donde se depositaran los siguientes archivos.

  • keystore.jks
  • saml2.cer así como saml2.pem
  • saml2_metadata.xml

Para la generación del JKS, se utiliza el siguiente comando de keytool:

keytool -genkey -keyalg RSA -alias saml2cert -keystore keystore.jks

Donde:

Parámetro Valor Descripción
-genkey   Se utiliza para generar una llave privada.
-keyalg RSA Nombre del algoritmo clave.
-alias saml2cert Alias para la llave.
-keystore keystore.jks Indica el nombre del archivo keystore que se generará.

Al ejecutar el comando se solicitará una contraseña para el KeyStore y posteriormente se solicitará además información como a continuación se muestra.

Posteriormente se debe ejecutar el siguiente comando keytool para generar el certificado.

keytool -export -keystore keystore.jks -alias saml2cert -file saml2.cer

Donde:

Parámetro Valor Descripción
-export   Se utiliza para exportar una llave privada.
-keystore keystore.jks Indica el archivo jks que se leerá para generar el certificado.
-alias saml2cert Alias que se buscará en el KeyStore.
-file saml2.cer Archivo de certificado donde se exportará la llave pública.

Nota: Al momento de exportar el certificado se solicitará la contraseña del KeyStore.

Y por último se ejecuta el comando OpenSSL, para la generación del archivo pem.

openssl x509 -inform der -in saml2.cer -out saml2.pem

Donde:

Parámetro Valor Descripción
-inform der El fichero de entrada o el de salida se encuentran en el formato format, que puede ser PEM o DER.
-in saml2.cert El CSR para firmar se encuentra en el fichero dado como argumento
-out saml2.pem El certificado firmado se almacenará en el fichero dado.

Realizando los anteriores pasos se proseguirá a configurar la conexión proyecto con WSO2 Identity Server utilizando Spring Security.

4.4.Configuración de Spring Security del proyecto

Como primer paso se debe crear un nuevo package (com.example.demo.sso) dentro del proyecto en el cual se creará la clase SecurityConfig donde se establece las configuraciones predeterminadas de seguridad basadas en el spring-security-saml-dsl-core usando en el método saml(), como a continuación se muestra:

package com.example.demo.sso;

import static org.springframework.security.extensions.saml2.config.SAMLConfigurer.saml;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;

import com.example.demo.services.SamlUserService;

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${saml2.metadata-path}")
    private String metadataPath;

    @Value("${saml2.sp.protocol}")
    private String spProtocol;

    @Value("${saml2.sp.host}")
    private String spHost;

    @Value("${saml2.sp.path}")
    private String spBashPath;

    @Value("${saml2.sp.key-store.file}")
    private String keyStoreFile;

    @Value("${saml2.sp.key-store.password}")
    private String keyStorePassword;

    @Value("${saml2.sp.key-store.alias}")
    private String keyStoreAlias;

    @Autowired
    private SamlUserService samlUserService;

  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    http
      .csrf().and()
      .authorizeRequests()
        .antMatchers("/saml/**").permitAll()
        .anyRequest().authenticated()
        .and()
      .apply(saml())
      	.userDetailsService(samlUserService)
        .serviceProvider()
          .protocol(spProtocol)
          .hostname(spHost)
          .basePath(spBashPath)
          .keyStore()
            .storeFilePath(keyStoreFile)
            .keyPassword(keyStorePassword)
            .keyname(keyStoreAlias)
          .and()
        .and()
        .identityProvider()
          .metadataFilePath(metadataPath)
        .and()
    .and();
  }
}

4.5 Explicaciones del código anterior

Anotación Descripción
@EnableWebSecurity Anotación que permite que Spring encuentre y aplique automáticamente la clase a la WebSecurity global.

Proporciona la configuración a través de HttpSecurity, le permite configurar su acceso en función de los patrones de URL, los puntos finales de autenticación, los controladores, etc.

@Configuration Anotación encargada de definir que la clase es una clase de configuración para Spring framework.
@EnableGlobalMethodSecurity Proporciona seguridad AOP en los métodos, algunas de las anotaciones que habilitará son PreAuthorize PostAuthorize y también tiene soporte para JSR-250.

securedEnabled: Determina si se deben habilitar las anotaciones seguras de Spring Security.

Extensión de Clase

Al extender de la clase abstracta WebSecurityConfigurerAdapter se proporciona una clase base conveniente para crear una instancia de WebSecurityConfigurer, que permite la personalización de WebSecurity, permitiendo la personalización anulando métodos.

La anotación @EnableWebSecurity y la clase WebSecurityConfigurerAdapter trabajan juntos para proporcionar seguridad basada en web. Al extender WebSecurityConfigurerAdapter y con unas pocas líneas de código, podemos hacer lo siguiente:

  • Requerir que el usuario esté autenticado antes de acceder a cualquier URL dentro de nuestra aplicación.
  • Posibilidad de crear un usuario con el nombre de usuario “N”, la contraseña “C” y el rol “R”.
  • Habilita la autenticación HTTP básica y basada en formularios.
  • Spring Security generará automáticamente una página de inicio de sesión y una página de éxito de cierre de sesión para usted.

Sobre escritura de configuración

Como se explicó anteriormente la anotacion @EnableWebSecurity ayuda con el trabajo de configurar un HttpSecurity el cual es similar al elemento XML <http> de Spring Security en la configuración del espacio de nombres.

Esto permite configurar la seguridad basada en web para solicitudes http específicas. De forma predeterminada, se aplicará a todas las solicitudes.

Métodos Descripción
.csrf().and() Agrega compatibilidad con CSRF(Cross-site request forgery o falsificación de petición en sitios cruzados). Esto se activa de forma predeterminada cuando se utiliza el constructor predeterminado de WebSecurityConfigurerAdapter.
.authorizeRequests()

.antMatchers(“/saml/**”).permitAll()

.anyRequest().authenticated()

.and()

Permite restringir el acceso basado en HttpServletRequest.

Con la configuración de antMatchers, se requiere autenticación solo en la  URL “/saml/**“y otorgara acceso a todos los usuarios.

.apply(saml())

.userDetailsService(samlUserService)

.serviceProvider()

.protocol(spProtocol)

.hostname(spHost)

.basePath(spBashPath)

.keyStore()

.storeFilePath(keyStoreFile)

.keyPassword(keyStorePassword)

.keyname(keyStoreAlias)

.and()

.and()

Aplica un SecurityConfigurer a este SecurityBuilder anulando cualquier SecurityConfigurer de la misma clase exacta.

Lo importante a destacar es el método saml(), que es un método estático que devuelve la instancia de singleton SAMLConfigurer que contiene los detalles del proveedor de autenticación, filtro y asignación de solicitudes de SAML2.

Cuando una aplicación recibe la respuesta SAML, primero validará el XML SAML, la validación incluye los identificadores de origen y destino, la hora de la sesión, la firma, etc.

Si el XML de respuesta es válido, SAML DSL llamará al método userDetailsService ().el cual se construyó un servicio de usuario personalizado para convertir el XML en un modelo de usuario personalizado.

Continuando con la configuración en la sección serviceProvider(), por lo general, cuando un usuario inicia sesión correctamente, el IDP publicará una respuesta SAML en /saml/SSO del proveedor de servicios.

Al recibir el SAML, un proveedor de servicios validará el XML, como parte de la validación, buscará la identificación de la entidad, el destino, la audiencia y otros detalles, cuando se publica una solicitud en la instancia de localhost, verificará el atributo de destino con el dominio de instancia local. Si ambos (atributo de destino SAML y nombre de instancia local) no coinciden, la validación de la solicitud fallará.

.identityProvider()

.metadataFilePath(metadataPath)

.and()

El método metadataFilePath(), busca la metadata en el archivo xml del IdP el cual se encarga de autenticar y autorizar al usuario. Para este ejemplo será el IdP Resident de WSO2.

Atributos

Como se puede ejemplificar en la clase SecurityConfig se han declarado los siguientes atributos que obtendrán en su mayoría su valor desde el archivo application.yml.

Atributo Valor
metadataPath ${saml2.metadata-path}
spProtocol ${saml2.sp.protocol}
spHost ${saml2.sp.host}
spBashPath ${saml2.sp.path}
keyStoreFile ${saml2.sp.key-store.file}
keyStorePassword ${saml2.sp.key-store.password}
keyStoreAlias ${saml2.sp.key-store.alias}
samlUserService Servicio customizado para la obtención de información del usuario autorizado.

4.6 Creación de clase Service y Model

Con la interfaz SAMLUserDetailsService donde los datos SAML se utilizan para obtener información sobre el usuario. Al implementar la interfaz ubican al usuario en un almacén de datos arbitrario en función de la información presente en SAMLCredential y devuelven dicha fecha en una forma de objeto UserModel específico de la aplicación.

Con la anterior explicación se debe crear un nuevo package el cual tendrá el nombre de com.example.demo.services y en donde se creará una clase java llamada SamlUserService en la cual se realizara un simple parseo de la información para su mejor uso posteriormente.

package com.example.demo.services;

import java.util.HashMap;
import java.util.Map;

import org.opensaml.saml2.core.Attribute;
import org.opensaml.xml.schema.XSString;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.saml.SAMLCredential;
import org.springframework.security.saml.userdetails.SAMLUserDetailsService;
import org.springframework.stereotype.Service;

import com.example.demo.models.UserModel;

@Service
public class SamlUserService implements SAMLUserDetailsService {

    @Override
    public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
        Map<String, String> attributes = new HashMap<String, String>();
        String userID = credential.getNameID().getValue();
        for (Attribute element : credential.getAttributes()) {
            String name = element.getName().replace("http://wso2.org/claims/", "");
            XSString value = (XSString) element.getAttributeValues().get(0);
            attributes.put(name, value.getValue());
        }
        return new UserModel(userID, attributes.get("givenname"), attributes.get("emailaddress"));
    }
}

Al sobrescribir el método loadUserBySAML() el cual identifica la cuenta local del usuario al que hace referencia en los datos en la aserción SAML y devuelve el objeto UserModel que describe al usuario (id, givenname y emailladdress).

Para ello  se debe crear un nuevo package el cual tendrá el nombre de com.example.demo.models y en donde se creará una clase java llamada UserModel en la cual se manejara la información del usuario de forma más sencilla.

package com.example.demo.models;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public class UserModel {

    private String id;
    private String givenname;
    private String emailaddress;

    public UserModel(String id, String givenname, String emailaddress) {
        this.id = id;
        this.givenname = givenname;
        this.emailaddress = emailaddress;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getGivenname() {
        return givenname;
    }

    public void setGivenname(String givenname) {
        this.givenname = givenname;
    }

    public String getEmailaddress() {
        return emailaddress;
    }

    public void setEmailaddress(String emailaddress) {
        this.emailaddress = emailaddress;
    }
    
}

Nota: las notaciones @Getter y @ToString permiten que la librería lombok genere automáticamente el método predeterminado.

4.7 Creación de clase Controller

Unas de las ventajas de utilizar Spring para construir servicios web RESTful, son las solicitudes HTTP las cuales se pueden manejar por un controlador. Estos componentes se identifican mediante la anotación @RestController o @Controller.

Como se indico en el archivo application.yml el path sera “/“, el cual por medio de la anotación @GetMapping ingresara al método index en donde se realizará una conversión del método  getPrincipal() al UserModel, esto es posible ya que en la clase de configuración SecurityConfig se declaró que el servicio SamlUserService sería el encargado de la clase UserDetails la cual a sido cambiada en la respuesta por UserModel.

Dicho lo anterior, se debe crear un nuevo package el cual tendrá el nombre de com.example.demo.controllers y en donde se creará una clase java llamada LoginController.

package com.example.demo.controllers;

import org.springframework.security.providers.ExpiringUsernameAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.demo.models.UserModel;

@Controller
@RequestMapping(path = "/", method = RequestMethod.GET)
public class LoginController {
 
    @GetMapping(path = "/")
    public ModelAndView index(ExpiringUsernameAuthenticationToken userToken) {
        ModelAndView mav = new ModelAndView("index");
        UserModel user = (UserModel) userToken.getPrincipal();
        mav.addObject("user", user);
        return mav;	
    }
}

Creación de HTML y CSS

Con la finalidad de interactuar con el formulario que WSO2 Identity Server muestra al autenticar los usuarios, se debe crear una página html en la cual podremos interactuar, con la finalidad de cumplir este proceso se debe crear en la carpeta src/main/resources/templates el archivo index.html en el cual hará referencia los datos del usuario que se manejan en la clase UserModel y en el controller se lo hizo el renombre de user (línea 20 de la clase Controller).

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Cache-Control" content="private" />
<meta http-equiv="Cache-Control" content="no-store" />
<meta http-equiv="Pragma" content="no-cache" />
<link th:href="@{/styles/cssandjs/main.css}" rel="stylesheet" />

<title>Spring Security SAML Example</title>
</head>
<body>
    <img src="/styles/image/spring-boot-600x300.png" style="width: 10%">
    <img src="/styles/image/tech-spring-security.width-1024.png"
        style="width: 13%">
    <img src="/styles/image/WSO2_Software_Logo.png" style="width: 10%">
    <div class="login">
        <h1>Congratulations on logging in with SAML2</h1>
        <h1>
            Welcome <span style="font-weight: bold" th:text="${user.id}"></span>

        </h1>
        <a href="/saml/logout/"><button
                class="btn btn-primary btn-block btn-large">Logout</button> </a>
    </div>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <div>
        <table style="width: 0%">
        <thead>
            <tr>
                <th>Atribute</th>
                <th>Value</th>
            </tr>
        </thead>
            <tbody>
                <tr>
                    <td>givenname</td>
                    <td><span th:text="${user.givenname}"></span></td>
                </tr>
                <tr>
                    <td>emailaddress</td>
                    <td><span th:text="${user.emailaddress}"></span></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

Ya que se trata de un archivo html se puede incluir el performance con las clases css, las cuales pueden ser de las preferencias de cada persona, para mayor referencia se puede visitar la pagina https://templated.co/. Y solo basta agregar la referencia de la clase css, que se debe crear en la ruta src/main/resources/styles/cssandjs, en el html con la siguiente instrucción.

<link th:href="@{/styles/cssandjs/main.css}" rel="stylesheet" />

5. Creación de Service Provider en WSO2

Para iniciar se debe iniciar el servicio de WSO2 Identity Server, si no está encendido y para ello se debe ejecutar el siguiente comando dentro de la carpeta bin de la distribución de WSO2  Identity Server que se esté manejando.

sh wso2server.sh

Iniciado el servicio se debe seguir las siguientes instrucciones:

  • Iniciar sesión en la Consola de Administración con el usuario administrador.

consola de atribución

  • Navegar al menú principal para acceder al menú Identidad.
  • Hacer clic en Agregar en Proveedores de servicios.
  • Completar el formulario con la siguiente información:
    • Service Provider Name: SpringSAML2
    • Description: Spring Security with SAML2
  • Hacer clic en Register para agregar el nuevo proveedor de servicios.

  • Aparecerá la pantalla Proveedores de servicios. En el cual se debe pegar el certificado de la aplicación en el campo Aplication Certificate. Si no se cuenta con el certificado se debe seguir los siguientes pasos:
    • Situarse en la carpeta dentro de la versión de WSO2 Identity Server /repository/resources/security
    • Abrir una terminal y ejecutar los siguientes comandos.
    • Para exportar el certificado de keystone. El certificado exportado estará en formato binario.
keytool -export -keystore wso2carbon.jks -alias wso2carbon -file wso2carbon.crt
    • Convertir el certificado codificado en binario anterior en un certificado codificado PEM
openssl x509 -inform der -in wso2carbon.crt -out wso2carbon.pem
  • En la información del Proveedor de Servicios, haga clic en los botones de flecha para expandir los formularios de Claim Configuration y Inbound Authentication Configuration . En los cuales:
  • Claim Configuration: donde se deben configurar los claims que serán enviados en los Assertions, en lo cual se usará el Dialecto de los claim local (wso2.org) y en los Claims solicitados (Requested Claims) se agregan los claims de emailaddress y givenname.

  • Inbound Authentication Configuration: la responsabilidad del componente del autenticador entrante es identificar y analizar todas las solicitudes de autenticación entrantes y luego generar la respuesta correspondiente. Un autenticador entrante determinado tiene dos partes:
    • Procesador de solicitudes
    • Generador de respuestas

Para configurar la autenticación entrante o Inbound Authentication se debe dar clic en el botón de Configure, el cual se redireccionará al formulario en el cual se solicitará la información para establecer la conexión entre WSO2 Identity Server y la aplicación que se a generado anteriormente.

Para ello se debe llenar el formulario con la siguiente información:

Campo Valor Descripción
Issuer http://localhost:8080/saml/metadata Este es el elemento <saml: Issuer> que contiene el identificador único del proveedor de servicios. Este es también el valor de emisor especificado en la solicitud de autenticación SAML emitida por el proveedor de servicios.
Assertion Consumer URLs http://localhost:8080

http://localhost:8080/saml/SSO

http://localhost:8080/saml/metadata

Esta es la URL a la que se debe redirigir el navegador después de que la autenticación sea exitosa.
Enable Response Signing Seleccionado Firma las respuestas SAML2 devueltas después del proceso de autenticación.
Enable Signature Validation in Authentication Requests and Logout Requests Seleccionado Esto especifica si el proveedor de identidad debe validar la firma de la solicitud de autenticación SAML2 y la solicitud de cierre de sesión SAML2 que envía el proveedor de servicios.
Enable Single Logout Seleccionado Si el cierre de sesión único está habilitado, el proveedor de identidad envía solicitudes de cierre de sesión a todos los proveedores de servicios.
Enable Attribute Profile Seleccionado El servidor de identidad proporciona soporte para un perfil de atributo básico donde el proveedor de identidad puede incluir los atributos del usuario en las afirmaciones SAML como parte de la declaración de atributos
Include Attributes in the Response Always Seleccionado El proveedor de identidad siempre incluye los valores de los atributos relacionados con las afirmaciones seleccionadas en la declaración de atributos de SAML.
Enable IdP Initiated SSO Seleccionado Cuando está habilitado, no se requiere que el proveedor de servicios envíe la solicitud SAML2.

Posteriormente se debe dar clic en el botón de Update para actualizar la información en el Service Provider.

Terminado la configuración del Service Provider, solo resta obtener la meta data del Identity Provider para ello debe hacer clic en la opción de Resident en Identity Providers, el cual lo redireccionará al formulario con la información del IdP.

Haga clic en el botón de flecha para expandir los formularios de Inbound Authentication Configuration, expanda la pestaña de SAML2 Web SSO Configuration haga clic y en botón de Download SAML Metadata.

Una vez descargada la metadata, se renombrara el archivo xml por el de saml2_metadata y se colocará en la ruta src/main/resources/static .

5.1 Pruebas – Creación de un usuario de prueba

Para crear un nuevo usuario en la consola de administración de WSO2 Identity Server se deben seguir los siguientes pasos:

  • Dar clic Add (Agregar), en Users and Roles.
  • Clic en Add New User, en la página donde se redireccionó la consola.
  • Se pedirá llenar un formulario el cual contiene la información básica del usuario, como son Username y Password:
Campo Valor
Username Prueba
Password qazse4159
Confirm Password qazse4159

  • Posteriormente debe salir el mensaje que se agregó correctamente el nuevo usuario.

  • Con ello se presentará la lista de los usuarios que se tienen registrados, en donde se deberá dar clic en la opción User Profile del usuario recién creado, en donde se mostrará un nuevo formulario que contendrá más información del usuario.
Campo Valor Obligatorio
First Name Prueba Si
Last Name Prueba Si
Organization   No
Country   No
Email prueba@prueba.com Si
Telephone   No
Mobile   No
IM   No
URL   No
Department   No

  • Ahora se debe dar clic Add (Agregar), en Users and Roles.
  • Clic en Add New Role, en la página donde se redireccionó la consola.
  • Se pedirá llenar un formulario el cual contiene la información básica del rol.

Campo Valor
Role Name Login
  • Posteriormente se debe dar clic en el botón de Next, esto es para que despliegue la lista de los permisos que el rol puede tener, en este Rol solo se seleccionara el permiso de Login.

Finalmente se debe dar clic al botón de Finish.

  • Entonces se debe dar clic List, en Users and Roles, posteriormente  en la opción de Users se mostrará la lista de los usuarios.

  • En las opciones de los usuarios, se da clic en la opción de Assign Roles en el usuario Prueba que se creó, realizando esta acción se desplegará otra lista con los roles que pueden ser asignados al usuario, se selecciona el rol Login.

  • Una vez seleccionado el rol, se debe dar clic en el botón de Finish.

Una vez terminado los pasos anteriores, se tendrá que correr el proyecto de maven que se a generado en pasos anteriores, se puede hacer de varias maneras  como son:

1. Desde el IDE, para ello se debe seleccionar la carpeta del proyecto dar clic derecho y en la opción de Run As la sub opción Spring Boot App.

    • En caso de no encontrar en el IDE la opción antes mencionada se debe descargar un complemento llamado Spring Tool Suite (STS) en los casos de eclipse para realizar esta opción es en Help -> Eclipse MarketPlace

2. Desde consola, se debe situar desde una terminal sobre la carpeta raíz del proyecto y ejecutar por línea de comando los siguiente:

mvn clean install
  • Posteriormente.
java -jar target/demo-0.0.1-SNAPSHOT.jar

  • En la cual se mostrará el formulario de autenticación de WSO2 Identity Server, y en el cual se ingresa las credenciales del usuario anteriormente creado.

  • Posteriormente la aplicación SpringSAML2 solicita acceso a la información del perfil del usuario

  • Para esta prueba se selecciona la opción Select All y se le deberá dar clic en el botón de Approve. Donde se direccionará a la página que se construyó en el proyecto (index.html), y mostrará la información base del usuario (Nombre y correo electrónico).

6. Conclusiones y resumen

Como se ha podido revisar en este tutorial, utilizando el framework de Spring (Spring Boot y Spring Security) se puede establecer una conexión utilizando el protocolo SAML2 a WSO2 Identity Server de una forma más simple y rápida.

También se pudieron revisar componentes y protocolos que interactúan para autenticar y autorizar al usuario cuando intenta realizar un inicio de sesión.

De manera resumida el proyecto abarcó los siguientes puntos: 

  1. El usuario ingresa a la aplicación con la url: http://localhost:8080
  2. El controller de Spring intercepta la petición.
  3. Envía la petición de autenticación del usuario al SP.
  4. EL SP genera una solicitud de autenticación, y luego envía la solicitud y el usuario al IdP.
  5. Verifica en la base de datos (H2) la información del usuario. La cual está de forma predeterminada en WSO2 Identity Server.
  6. El IdP autentifica al usuario, y envía la respuesta de autenticación y la información del usuario de vuelta al SP.
  7. El SP verifica la respuesta del IdP. Envía la solicitud al recurso que devuelve el contenido solicitado originalmente (Spring Security).
  8. Realiza el mapping de la respuesta de la solicitud para mostrarlo en el html.

Referencias:

  • http://stuff.gpul.org/2004_cripto/doc/chuleta_openssl.pdf
  • https://docs.wso2.com/display/IS570/Configuring+Single+Sign-On
  • https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#saml2
  • https://docs.wso2.com/display/IS570/Configuring+Inbound+Provisioning+for+a+Service+Provider
  • https://medium.com/@piraveenaparalogarajah/add-saml-authentication-to-spring-boot-app-with-wso2-is-17ed3d12c60d
  • https://mencrypto.com/saml2-with-spring-and-wso2-is/
  • http://www.techsams.com/java/spring/sso/onelogin/single-sign-on-with-spring-saml.html
  • https://github.com/Mencrypto/SSOWSO2ISSPRING – Connect to preview
  • https://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/#wsca
  • https://dzone.com/articles/get-started-with-spring-boot-saml-and-okta
  • https://blog.joshsoftware.com/2020/04/22/single-sign-on-with-saml-and-spring-boot/

¡Contáctanos y te ayudaremos con la integración de WSO2 IS!