Autenticación SAML 2.0 saml-2-0-authentication
Aprenda a configurar y autenticar usuarios finales (no autores de AEM) en un IDP compatible con SAML 2.0 de su elección.
¿Qué es SAML para AEM as a Cloud Service?
La integración de SAML 2.0 con AEM Publish (o Preview) permite a los usuarios finales de una experiencia web basada en AEM autenticarse en un IDP (proveedor de identidad) que no es de Adobe y acceder a AEM como un usuario autorizado con nombre.
El flujo típico de una integración de AEM Publish SAML es el siguiente:
-
El usuario realiza una solicitud a AEM Publish que indica que se requiere autenticación.
- El usuario solicita un recurso protegido por CUG/ACL.
- El usuario solicita un recurso que está sujeto a un requisito de autenticación.
- El usuario sigue un vínculo al extremo de inicio de sesión de AEM (es decir,
/system/sling/login) que solicita explícitamente la acción de inicio de sesión.
-
AEM realiza una AuthnRequest al IDP, en la que se solicita que el IDP inicie el proceso de autenticación.
-
El usuario se autentica en IDP.
- El IDP solicita credenciales al usuario.
- El usuario ya se ha autenticado con el IDP y no tiene que proporcionar más credenciales.
-
IDP genera una afirmación de SAML que contiene los datos del usuario y la firma utilizando el certificado privado del IDP.
-
IDP envía la afirmación de SAML a través de HTTP POST, a través del explorador web del usuario (RESPECTIVE_PROTECTED_PATH/saml_login), a AEM Publish.
-
AEM Publish recibe la afirmación de SAML y valida la integridad y autenticidad de la afirmación de SAML utilizando el certificado público IDP.
-
AEM Publish administra el registro de usuario de AEM en función de la configuración OSGi de SAML 2.0 y el contenido de la aserción SAML.
- Crea un usuario
- Sincroniza atributos de usuario
- Actualiza la pertenencia a grupos de usuarios de AEM
-
AEM Publish establece la cookie
login-tokende AEM en la respuesta HTTP, que se utiliza para autenticar solicitudes posteriores en AEM Publish. -
AEM Publish redirige al usuario a la dirección URL en AEM Publish según se especifica en la cookie
saml_request_path.
Introducción a la configuración
Este vídeo explica cómo configurar la integración de SAML 2.0 con el servicio de publicación de AEM as a Cloud Service y cómo utilizar Okta como IDP.
Requisitos previos
Se requiere lo siguiente al configurar la autenticación SAML 2.0:
- Acceso del administrador de implementación a Cloud Manager
- Acceso de administrador de AEM al entorno de AEM as a Cloud Service
- Acceso de administrador al IDP
- Opcionalmente, acceso a un par de claves pública y privada utilizado para cifrar cargas SAML
- Páginas de AEM Sites (o árboles de páginas), publicadas en AEM Publish y protegidas por grupos de usuarios cerrados (CUG)
SAML 2.0 solo se admite para autenticar usuarios en AEM Publish o Preview. Para administrar la autenticación del autor de AEM que usa y IDP, integre el IDP con Adobe IMS.
Instalación del certificado público IDP en AEM
El certificado público del IDP se añade al repositorio de confianza global de AEM y se utiliza para validar que la afirmación de SAML enviada por el IDP es válida.
- El usuario se autentica en IDP.
- IDP genera una afirmación de SAML que contiene los datos del usuario.
- IDP firma la afirmación de SAML usando el certificado privado de IDP.
- IDP inicia un POST HTTP del lado del cliente en el extremo SAML de AEM Publish (
.../saml_login) que incluye la afirmación de SAML firmada. - AEM Publish recibe el POST HTTP que contiene la afirmación de SAML firmada, puede validar la firma mediante el certificado público IDP.
-
Obtenga el archivo de certificado público del IDP. Este certificado permite a AEM validar la afirmación de SAML proporcionada a AEM por el IDP.
El certificado está en formato PEM y debe tener un aspecto similar al siguiente:
code language-none -----BEGIN CERTIFICATE----- MIIC4jCBAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJV ... m0eo2USlSRTVl7QHRTuiuSThHpLKQQ== -----END CERTIFICATE----- -
Inicie sesión en AEM Author como administrador de AEM.
-
Vaya a Herramientas > Seguridad > Almacén de confianza.
-
Cree o abra el Almacén de confianza global. Si crea un almacén de confianza global, guarde la contraseña en un lugar seguro.
-
Expandir Agregar certificado del archivo CER.
-
Seleccione Seleccionar archivo de certificado y cargue el archivo de certificado proporcionado por el IDP.
-
Deje Asignar certificado al usuario en blanco.
-
Seleccione Enviar.
-
El certificado recién agregado aparece encima de la sección Agregar certificado del archivo CRT.
-
Tome nota del alias, ya que este valor se usa en la configuración OSGi del Controlador de autenticación SAML 2.0.
-
Seleccione Guardar y cerrar.
El repositorio de confianza global está configurado con el certificado público del IDP en AEM Author, pero como SAML solo se utiliza en AEM Publish, el repositorio de confianza global debe replicarse en AEM Publish para que el certificado público IDP sea accesible allí.
-
Vaya a Herramientas > Implementación > Paquetes.
-
Creación de un paquete
- Nombre del paquete:
Global Trust Store - Versión:
1.0.0 - Grupo:
com.your.company
- Nombre del paquete:
-
Edite el nuevo paquete de Almacén de confianza global.
-
Seleccione la ficha Filtros y agregue un filtro para la ruta raíz
/etc/truststore. -
Seleccione Listo y luego Guardar.
-
Seleccione el botón Generar para el paquete de Almacén de confianza global.
-
Una vez generado, seleccione Más > Replicar para activar el nodo Almacén de confianza global (
/etc/truststore) en AEM Publish.
Crear almacén de claves del servicio de autenticación authentication-service-keystore
Es necesario crear un almacén de claves para el servicio de autenticación cuando la propiedad de configuración OSGi del controlador de autenticación SAML 2.0 handleLogout está establecida en true o cuando se requiere cifrado de firma AuthnRequest/aserción SAML
-
Inicie sesión en AEM Author como administrador de AEM para cargar la clave privada.
-
Vaya a Herramientas > Seguridad > Usuarios, seleccione el usuario authentication-service y seleccione Propiedades en la barra de acciones superior.
-
Seleccione la pestaña Keystore.
-
Cree o abra el repositorio de claves. Si crea un almacén de claves, mantenga la contraseña a salvo.
- Un almacén de claves público/privado está instalado en este almacén de claves solo si se requiere cifrado de firma AuthnRequest/aserción SAML.
- Si esta integración de SAML admite el cierre de sesión, pero no la firma AuthnRequest/aserción SAML, basta con un almacén de claves vacío.
-
Seleccione Guardar y cerrar.
-
Cree un paquete que contenga el usuario authentication-service actualizado.
Usar la siguiente solución temporal mediante paquetes :
-
Vaya a Herramientas > Implementación > Paquetes.
-
Creación de un paquete
- Nombre del paquete:
Authentication Service - Versión:
1.0.0 - Grupo:
com.your.company
- Nombre del paquete:
-
Edite el nuevo paquete Almacenamiento de claves del servicio de autenticación.
-
Seleccione la ficha Filtros y agregue un filtro para la ruta raíz
/home/users/system/cq:services/internal/security/<AUTHENTICATION SERVICE UUID>/keystore.- Para encontrar
<AUTHENTICATION SERVICE UUID>, vaya a Herramientas > Seguridad > Usuarios y seleccione el usuario authentication-service. El UUID es la última parte de la dirección URL.
- Para encontrar
-
Seleccione Listo y luego Guardar.
-
Seleccione el botón Generar para el paquete de Almacenamiento de claves del servicio de autenticación.
-
Una vez compilado, seleccione Más > Replicar para activar el almacén de claves del servicio de autenticación en AEM Publish.
-
Instalación del par de claves pública y privada de AEM install-aem-public-private-key-pair
La instalación del par de claves pública y privada de AEM es opcional
AEM Publish se puede configurar para firmar solicitudes de autenticación (a IDP) y cifrar aserciones de SAML (a AEM). Esto se logra proporcionando una clave privada a AEM Publish y haciendo coincidir la clave pública con el IDP.
AuthnRequest (la solicitud al IDP desde AEM Publish que inicia el proceso de inicio de sesión) puede firmarla AEM Publish. Para ello, AEM Publish firma AuthnRequest con la clave privada, de modo que el IDP valide la firma con la clave pública. Esto garantiza al IDP que AuthnRequest se inició y fue solicitado por AEM Publish, y no por un tercero malicioso.
- El usuario realiza una solicitud HTTP a AEM Publish que resulta en una solicitud de autenticación SAML al IDP.
- AEM Publish genera la solicitud SAML para enviarla al IDP.
- AEM Publish firma la solicitud SAML con la clave privada de AEM.
- AEM Publish inicia AuthnRequest, un redireccionamiento del lado del cliente HTTP al IDP que contiene la solicitud SAML firmada.
- IDP recibe la AuthnRequest y valida la firma con la clave pública de AEM, lo que garantiza que AEM Publish inició la AuthnRequest.
- A continuación, AEM Publish valida la integridad y autenticidad de la afirmación de SAML descifrada mediante el certificado público IDP.
Toda la comunicación HTTP entre IDP y AEM Publish debe ser a través de HTTPS y, por lo tanto, segura de forma predeterminada. Sin embargo, según sea necesario, las afirmaciones de SAML pueden cifrarse en el caso de que se requiera confidencialidad adicional además de la proporcionada por HTTPS. Para ello, el IDP cifra los datos de aserción de SAML utilizando la clave privada y AEM Publish descifra la aserción de SAML utilizando la clave privada.
- El usuario se autentica en IDP.
- IDP genera una afirmación de SAML que contiene los datos del usuario y la firma utilizando el certificado privado del IDP.
- A continuación, IDP cifra la afirmación de SAML con la clave pública de AEM, que requiere la clave privada de AEM para descifrar.
- La afirmación de SAML cifrada se envía a AEM Publish a través del explorador web del usuario.
- AEM Publish recibe la afirmación de SAML y la descifra utilizando la clave privada de AEM.
- IDP solicita al usuario que se autentique.
Tanto la firma de AuthnRequest como el cifrado de aserción de SAML son opcionales; sin embargo, ambos están habilitados mediante la propiedad de configuración OSGi del controlador de autenticación SAML 2.0, lo que significa que se pueden usar ambos o ninguno.useEncryption
-
Obtenga la clave pública, la clave privada (PKCS#8 en formato DER) y el archivo de cadena de certificados (puede ser la clave pública) utilizados para firmar AuthnRequest y cifre la afirmación de SAML. Las claves las suele proporcionar el equipo de seguridad de la organización de TI.
- Se puede generar un par de claves autofirmadas con openssl:
code language-none $ openssl req -x509 -sha256 -days 365 -newkey rsa:4096 -keyout aem-private.key -out aem-public.crt # Provide a password (keep in safe place), and other requested certificate information # Convert the keys to AEM's required format $ openssl rsa -in aem-private.key -outform der -out aem-private.der $ openssl pkcs8 -topk8 -inform der -nocrypt -in aem-private.der -outform der -out aem-private-pkcs8.der -
Cargue la clave pública al IDP.
- Utilizando el método
opensslanterior, la clave pública es el archivoaem-public.crt.
- Utilizando el método
-
Inicie sesión en AEM Author como administrador de AEM para cargar la clave privada.
-
Vaya a Herramientas > Seguridad > Almacén de confianza, seleccione el usuario servicio de autenticación y seleccione Propiedades en la barra de acciones superior.
-
Vaya a Herramientas > Seguridad > Usuarios, seleccione el usuario authentication-service y seleccione Propiedades en la barra de acciones superior.
-
Seleccione la pestaña Keystore.
-
Cree o abra el repositorio de claves. Si crea un almacén de claves, mantenga la contraseña a salvo.
-
Seleccione Agregar clave privada desde el archivo DER y agregue la clave privada y el archivo de cadena a AEM:
- Alias: proporcione un nombre significativo, a menudo el nombre del IDP.
- Archivo de clave privada: Cargue el archivo de clave privada (PKCS#8 en formato DER).
- Utilizando el método
opensslanterior, este es el archivoaem-private-pkcs8.der
- Utilizando el método
- Seleccionar archivo de cadena de certificados: cargue el archivo de cadena que lo acompaña (puede ser la clave pública).
- Utilizando el método
opensslanterior, este es el archivoaem-public.crt
- Utilizando el método
- Seleccionar Enviar
-
El certificado recién agregado aparece encima de la sección Agregar certificado del archivo CRT.
- Tome nota del alias, ya que se utiliza en la configuración OSGi del controlador de autenticación SAML 2.0
-
Seleccione Guardar y cerrar.
-
Cree un paquete que contenga el usuario authentication-service actualizado.
Usar la siguiente solución temporal mediante paquetes :
-
Vaya a Herramientas > Implementación > Paquetes.
-
Creación de un paquete
- Nombre del paquete:
Authentication Service - Versión:
1.0.0 - Grupo:
com.your.company
- Nombre del paquete:
-
Edite el nuevo paquete Almacenamiento de claves del servicio de autenticación.
-
Seleccione la ficha Filtros y agregue un filtro para la ruta raíz
/home/users/system/cq:services/internal/security/<AUTHENTICATION SERVICE UUID>/keystore.- Para encontrar
<AUTHENTICATION SERVICE UUID>, vaya a Herramientas > Seguridad > Usuarios y seleccione el usuario authentication-service. El UUID es la última parte de la dirección URL.
- Para encontrar
-
Seleccione Listo y luego Guardar.
-
Seleccione el botón Generar para el paquete de Almacenamiento de claves del servicio de autenticación.
-
Una vez compilado, seleccione Más > Replicar para activar el almacén de claves del servicio de autenticación en AEM Publish.
-
Configurar el controlador de autenticación SAML 2.0 configure-saml-2-0-authentication-handler
La configuración de SAML de AEM se realiza a través de la configuración OSGi Controlador de autenticación Adobe Granite SAML 2.0.
La configuración es una configuración de fábrica de OSGi, lo que significa que un solo servicio de publicación de AEM as a Cloud Service puede tener varias configuraciones de SAML que cubran árboles de recursos discretos del repositorio; esto resulta útil para implementaciones de AEM de varios sitios.
Configuración OSGi del Controlador de autenticación SAML 2.0 de Adobe Granite configure-saml-2-0-authentication-handler-osgi-configuration
| table 0-row-6 1-row-6 2-row-6 3-row-6 4-row-6 5-row-6 6-row-6 7-row-6 8-row-6 9-row-6 10-row-6 11-row-6 12-row-6 13-row-6 14-row-6 15-row-6 16-row-6 17-row-6 18-row-6 19-row-6 20-row-6 21-row-6 22-row-6 23-row-6 24-row-6 25-row-6 26-row-6 27-row-6 3-align-center 4-align-center 10-align-center 11-align-center 17-align-center 18-align-center 24-align-center 25-align-center 31-align-center 32-align-center 38-align-center 39-align-center 45-align-center 46-align-center 52-align-center 53-align-center 59-align-center 60-align-center 66-align-center 67-align-center 73-align-center 74-align-center 80-align-center 81-align-center 87-align-center 88-align-center 94-align-center 95-align-center 101-align-center 102-align-center 108-align-center 109-align-center 115-align-center 116-align-center 122-align-center 123-align-center 129-align-center 130-align-center 136-align-center 137-align-center 143-align-center 144-align-center 150-align-center 151-align-center 157-align-center 158-align-center 164-align-center 165-align-center 171-align-center 172-align-center 178-align-center 179-align-center 185-align-center 186-align-center 192-align-center 193-align-center | |||||
|---|---|---|---|---|---|
| Propiedad OSGi | Necesario | Formato de valor | Valor predeterminado | Descripción | |
| Rutas | path |
✔ | Matriz de cadenas | / |
Rutas de AEM para las que se utiliza este controlador de autenticación. |
| URL de IDP | idpUrl |
✔ | Cadena | Dirección URL de IDP a la que se envía la solicitud de autenticación SAML. | |
| Alias de certificado IDP | idpCertAlias |
✔ | Cadena | Alias del certificado IDP encontrado en el repositorio de confianza global de AEM | |
| Redirección HTTP de IDP | idpHttpRedirect |
✘ | Booleano | false |
Indica si hay un redireccionamiento HTTP a la URL de IDP en lugar de enviar una AuthnRequest. Se estableció en true para la autenticación iniciada por IDP. |
| Identificador de IDP | idpIdentifier |
✘ | Cadena | ID de IDP único para garantizar la exclusividad de usuarios y grupos de AEM. Si está vacío, se utiliza serviceProviderEntityId en su lugar. |
|
| URL de servicio de consumidor de afirmación | assertionConsumerServiceURL |
✘ | Cadena | Atributo de URL AssertionConsumerServiceURL en AuthnRequest que especifica dónde se debe enviar el mensaje <Response> a AEM. |
|
| ID de entidad de SP | serviceProviderEntityId |
✔ | Cadena | Identifica de forma exclusiva a AEM con el IDP; normalmente es el nombre de host de AEM. | |
| Cifrado SP | useEncryption |
✘ | Booleano | true |
Indica si el IDP cifra las afirmaciones de SAML. Requiere que se establezcan spPrivateKeyAlias y keyStorePassword. |
| Alias de clave privada SP | spPrivateKeyAlias |
✘ | Cadena | Alias de la clave privada en el almacén de claves del usuario authentication-service. Obligatorio si useEncryption está establecido en true. |
|
| Contraseña del almacén de claves SP | keyStorePassword |
✘ | Cadena | La contraseña del almacén de claves del usuario del servicio de autenticación. Obligatorio si useEncryption está establecido en true. |
|
| Redirección predeterminada | defaultRedirectUrl |
✘ | Cadena | / |
La URL de redireccionamiento predeterminada después de la autenticación correcta. Puede ser relativo al host de AEM (por ejemplo, /content/wknd/us/en/html). |
| Atributo de ID de usuario | userIDAttribute |
✘ | Cadena | uid |
Nombre del atributo de afirmación de SAML que contiene el ID de usuario del usuario de AEM. Dejar vacío para utilizar Subject:NameId. |
| Crear automáticamente usuarios de AEM | createUser |
✘ | Booleano | true |
Indica si los usuarios de AEM se crean con una autenticación correcta. |
| Ruta intermedia del usuario de AEM | userIntermediatePath |
✘ | Cadena | Al crear usuarios de AEM, este valor se usa como ruta intermedia (por ejemplo, /home/users/<userIntermediatePath>/jane@wknd.com). Requiere que createUser se establezca en true. |
|
| Atributos de usuario de AEM | synchronizeAttributes |
✘ | Matriz de cadenas | Lista de asignaciones de atributos SAML que se almacenarán en el usuario de AEM, con el formato [ "saml-attribute-name=path/relative/to/user/node" ] (por ejemplo, [ "firstName=profile/givenName" ]). Ver la lista completa de atributos nativos de AEM. |
|
| Añadir usuario a grupos de AEM | addGroupMemberships |
✘ | Booleano | true |
Indica si se agrega automáticamente un usuario de AEM a los grupos de usuarios de AEM después de la autenticación correcta. |
| atributo de pertenencia a grupo de AEM | groupMembershipAttribute |
✘ | Cadena | groupMembership |
Nombre del atributo de afirmación de SAML que contiene una lista de grupos de usuarios de AEM a los que se debe agregar el usuario. Requiere que addGroupMemberships se establezca en true. |
| Grupos de AEM predeterminados | defaultGroups |
✘ | Matriz de cadenas | Siempre se agrega una lista de usuarios autenticados de grupos de usuarios de AEM a (por ejemplo, [ "wknd-user" ]). Requiere que addGroupMemberships se establezca en true. |
|
| Formato de directiva de IDP de nombre | nameIdFormat |
✘ | Cadena | urn:oasis:names:tc:SAML:2.0:nameid-format:transient |
Valor del parámetro de formato NameIDPolicy que se enviará en el mensaje AuthnRequest. |
| Almacenar respuesta de SAML | storeSAMLResponse |
✘ | Booleano | false |
Indica si el valor samlResponse está almacenado en el nodo cq:User de AEM. |
| Controlar cierre de sesión | handleLogout |
✘ | Booleano | false |
Indica si este controlador de autenticación SAML administra la solicitud de cierre de sesión. Requiere que se establezca logoutUrl. |
| URL de desconexión | logoutUrl |
✘ | Cadena | URL de IDP a la que se envía la solicitud de cierre de sesión de SAML. Obligatorio si handleLogout está establecido en true. |
|
| Tolerancia del reloj | clockTolerance |
✘ | Entero | 60 |
La tolerancia de sesgo de reloj de IDP y AEM (SP) al validar afirmaciones de SAML. |
| Método de resumen | digestMethod |
✘ | Cadena | http://www.w3.org/2001/04/xmlenc#sha256 |
Algoritmo de resumen que utiliza el IDP al firmar un mensaje SAML. |
| Método de firma | signatureMethod |
✘ | Cadena | http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 |
Algoritmo de firma que utiliza el IDP al firmar un mensaje SAML. |
| Tipo de sincronización de identidad | identitySyncType |
✘ | default o idp |
default |
No cambie el valor predeterminado from para AEM as a Cloud Service. |
| Clasificación del servicio | service.ranking |
✘ | Entero | 5002 |
Se prefieren configuraciones de clasificación más alta para el mismo path. |
Atributos de usuario de AEM aem-user-attributes
AEM utiliza los siguientes atributos de usuario, que se pueden rellenar mediante la propiedad synchronizeAttributes en la configuración OSGi del Controlador de autenticación SAML 2.0 de Adobe Granite. Cualquier atributo IDP se puede sincronizar con cualquier propiedad de usuario de AEM, pero la asignación a las propiedades de atributo de uso de AEM (enumeradas a continuación) permite que AEM los utilice de forma natural.
| table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 5-row-2 6-row-2 7-row-2 8-row-2 9-row-2 10-row-2 11-row-2 | |
|---|---|
| Atributo de usuario | Ruta de propiedad relativa desde el nodo rep:User |
Título (por ejemplo, Mrs) |
profile/title |
| Nombre dado (es decir, nombre) | profile/givenName |
| Apellido (es decir, apellido) | profile/familyName |
| Título de trabajo | profile/jobTitle |
| Dirección de correo electrónico | profile/email |
| Dirección | profile/street |
| Ciudad | profile/city |
| Código postal | profile/postalCode |
| País | profile/country |
| Número de teléfono | profile/phoneNumber |
| Acerca de mí | profile/aboutMe |
-
Cree un archivo de configuración OSGi en su proyecto en
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~saml.cfg.jsony ábralo en su IDE.- Cambiar
/wknd-examples/a/<project name>/ - El identificador después de
~en el nombre de archivo debe identificar de forma exclusiva esta configuración, por lo que puede ser el nombre del IDP, como...~okta.cfg.json. El valor debe ser alfanumérico y contener guiones.
- Cambiar
-
Pegue el siguiente JSON en el archivo
com.adobe.granite.auth.saml.SamlAuthenticationHandler~...cfg.jsony actualice las referenciaswkndsegún sea necesario.code language-json { "path": [ "/content/wknd", "/content/dam/wknd" ], "idpCertAlias": "$[env:SAML_IDP_CERT_ALIAS;default=certalias___1652125559800]", "idpIdentifier": "$[env:SAML_IDP_ID;default=http://www.okta.com/exk4z55r44Jz9C6am5d7]", "idpUrl": "$[env:SAML_IDP_URL;default=https://dev-5511372.okta.com/app/dev-5511372_aemasacloudservice_1/exk4z55r44Jz9C6am5d7/sso/saml]", "serviceProviderEntityId": "$[env:SAML_AEM_ID;default=https://publish-p123-e456.adobeaemcloud.com]", "useEncryption": false, "createUser": true, "userIntermediatePath": "wknd/idp", "synchronizeAttributes":[ "firstName=profile/givenName" ], "addGroupMemberships": true, "defaultGroups": [ "wknd-users" ] } -
Actualice los valores según sea necesario en el proyecto. Consulte el glosario de configuración OSGi del Controlador de autenticación SAML 2.0 anterior para obtener descripciones de las propiedades de configuración.
pathdebe contener los árboles de contenido protegidos por Grupos de usuarios cerrados (CUG) y requerir autenticación. Este controlador de autenticación debe ser responsable de proteger. -
Se recomienda, pero no es obligatorio, utilizar variables y secretos de entorno OSGi, cuando los valores pueden cambiar sin estar sincronizados con el ciclo de lanzamiento o cuando los valores difieren entre tipos de entorno/niveles de servicio similares. Los valores predeterminados se pueden establecer con la sintaxis
$[env:..;default=the-default-value]", como se muestra arriba.
Las configuraciones de OSGi por entorno (config.publish.dev, config.publish.stage y config.publish.prod) se pueden definir con atributos específicos si la configuración de SAML varía entre entornos.
Usar cifrado
Al cifrar AuthnRequest y la aserción SAML, se requieren las siguientes propiedades: useEncryption, spPrivateKeyAlias y keyStorePassword. El keyStorePassword contiene una contraseña; por lo tanto, el valor no debe almacenarse en el archivo de configuración OSGi, sino insertarse usando valores de configuración secretos
-
Abra
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~saml.cfg.jsonen su IDE. -
Agregue las tres propiedades
useEncryption,spPrivateKeyAliasykeyStorePasswordcomo se muestra a continuación.code language-json { "path": [ "/content/wknd", "/content/dam/wknd" ], "idpCertAlias": "$[env:SAML_IDP_CERT_ALIAS;default=certalias___1234567890]", "idpIdentifier": "$[env:SAML_IDP_ID;default=http://www.okta.com/abcdef1235678]", "idpUrl": "$[env:SAML_IDP_URL;default=https://dev-5511372.okta.com/app/dev-123567890_aemasacloudservice_1/abcdef1235678/sso/saml]", "serviceProviderEntityId": "$[env:SAML_AEM_ID;default=https://publish-p123-e456.adobeaemcloud.com]", "useEncryption": true, "spPrivateKeyAlias": "$[env:SAML_AEM_KEYSTORE_ALIAS;default=aem-saml-encryption]", "keyStorePassword": "$[secret:SAML_AEM_KEYSTORE_PASSWORD]", "createUser": true, "userIntermediatePath": "wknd/idp" "synchronizeAttributes":[ "firstName=profile/givenName" ], "addGroupMemberships": true, "defaultGroups": [ "wknd-users" ] } -
Las tres propiedades de configuración OSGi necesarias para el cifrado son:
useEncryptionse estableció entruespPrivateKeyAliascontiene el alias de entrada del almacén de claves para la clave privada utilizada por la integración de SAML.keyStorePasswordcontiene una variable de configuración secreta OSGi que contiene la contraseña del almacén de claves de usuarioauthentication-service.
Configurar el filtro de referente
Durante el proceso de autenticación SAML, el IDP inicia un POST HTTP del lado del cliente en el punto final .../saml_login de AEM Publish. Si el IDP y AEM Publish existen en un origen diferente, el Filtro de referente de AEM Publish se configura mediante la configuración OSGi para permitir HTTP POST desde el origen del IDP.
-
Cree (o edite) un archivo de configuración OSGi en su proyecto en
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/org.apache.sling.security.impl.ReferrerFilter.cfg.json.- Cambiar
/wknd-examples/a/<project name>/
- Cambiar
-
Asegúrese de que el valor
allow.emptyesté establecido entrue, de queallow.hosts(o, si lo prefiere,allow.hosts.regexp) contenga el origen del IDP y de quefilter.methodsincluyaPOST. La configuración de OSGi debe ser similar a:code language-json { "allow.empty": true, "allow.hosts.regexp": [ ], "allow.hosts": [ "$[env:SAML_IDP_REFERRER;default=dev-123567890.okta.com]" ], "filter.methods": [ "POST", ], "exclude.agents.regexp": [ ] }
AEM Publish admite una sola configuración de filtro de referente, por lo que debe combinar los requisitos de configuración de SAML con cualquier configuración existente.
Las configuraciones de OSGi por entorno (config.publish.dev, config.publish.stage y config.publish.prod) se pueden definir con atributos específicos si allow.hosts (o allow.hosts.regex) varían entre entornos.
Configuración del intercambio de recursos de origen cruzado (CORS)
Durante el proceso de autenticación SAML, el IDP inicia un POST HTTP del lado del cliente en el punto final .../saml_login de AEM Publish. Si el IDP y la publicación de AEM existen en hosts/dominios diferentes, el intercambio de recursos de origen de CRoss (CORS) de AEM Publish debe configurarse para permitir HTTP POST desde el host/dominio del IDP.
El encabezado Origin de esta solicitud HTTP POST suele tener un valor diferente al host de publicación de AEM, por lo que requiere la configuración CORS.
Al probar la autenticación SAML en AEM SDK local (localhost:4503), el IDP puede establecer el encabezado Origin en null. Si es así, agregue "null" a la lista alloworigin.
-
Cree un archivo de configuración OSGi en su proyecto en
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.adobe.granite.cors.impl.CORSPolicyImpl~saml.cfg.json- Cambiar
/wknd-examples/a su nombre de proyecto - El identificador después de
~en el nombre de archivo debe identificar de forma exclusiva esta configuración, por lo que puede ser el nombre del IDP, como...CORSPolicyImpl~okta.cfg.json. El valor debe ser alfanumérico y contener guiones.
- Cambiar
-
Pegue el siguiente JSON en el archivo
com.adobe.granite.cors.impl.CORSPolicyImpl~...cfg.json.
{
"alloworigin": [
"$[env:SAML_IDP_ORIGIN;default=https://dev-1234567890.okta.com]",
"null"
],
"allowedpaths": [
".*/saml_login"
],
"supportedmethods": [
"POST"
]
}
Las configuraciones de OSGi por entorno (config.publish.dev, config.publish.stage y config.publish.prod) se pueden definir con atributos específicos si alloworigin y allowedpaths varían entre entornos.
Configuración de AEM Dispatcher para permitir HTTP POST de SAML
Después de autenticarse correctamente en el IDP, el IDP orquestará un POST HTTP de vuelta al punto final /saml_login registrado de AEM (configurado en el IDP). Este POST HTTP para /saml_login está bloqueado de forma predeterminada en Dispatcher, por lo que debe permitirse explícitamente usando la siguiente regla de Dispatcher:
- Abra
dispatcher/src/conf.dispatcher.d/filters/filters.anyen su IDE. - Agregue al final del archivo una regla de permiso para POST HTTP a direcciones URL que terminen con
/saml_login.
...
# Allow SAML HTTP POST to ../saml_login end points
/0190 { /type "allow" /method "POST" /url "*/saml_login" }
Si está configurada la reescritura de URL en el servidor web Apache (dispatcher/src/conf.d/rewrites/rewrite.rules), asegúrese de que las solicitudes a los puntos finales .../saml_login no se manipulen accidentalmente.
Pertenencia a grupo dinámico
La pertenencia a grupos dinámicos es una característica de Apache Jackrabbit Oak que aumenta el rendimiento de la evaluación y el aprovisionamiento de grupos. En esta sección se describe cómo se almacenan los usuarios y grupos cuando se habilita esta función y cómo modificar la configuración del Controlador de autenticación SAML para habilitarlo para entornos nuevos o existentes.
Cómo habilitar la pertenencia a grupos dinámicos para usuarios de SAML en nuevos entornos
Para mejorar significativamente el rendimiento de la evaluación de grupos en nuevos entornos de AEM as a Cloud Service, se recomienda activar la función de pertenencia a grupos dinámicos en nuevos entornos.
También es un paso necesario cuando se activa la sincronización de datos. Más detalles aquí .
Para ello, agregue la siguiente propiedad al archivo de configuración OSGI:
/apps/example/osgiconfig/config.publish/com.adobe.granite.auth.saml.SamlAuthenticationHandler~example.cfg.json
Con esta configuración, los usuarios y grupos se crean como usuarios externos de Oak. En AEM, los usuarios y grupos externos tienen un(a) rep:principalName predeterminado compuesto(a) por [user name];[idp] o [group name];[idp].
Observe que las Listas de control de acceso (ACL) están asociadas al nombre principal de los usuarios o grupos.
Al implementar esta configuración en una implementación existente en la que anteriormente identitySyncType no se especificaba ni se establecía en default, se crearán nuevos usuarios y grupos y se deberá aplicar ACL a estos nuevos usuarios y grupos. Tenga en cuenta que los grupos externos no pueden contener usuarios locales. Repoinit se puede usar para crear ACL para grupos externos SAML, incluso si solo se crearán cuando el usuario inicie sesión.
Para evitar esta refactorización en ACL, se ha implementado una característica de migración estándar.
Almacenamiento de las suscripciones en grupos locales y externos con pertenencia a grupos dinámicos
En los grupos locales, los miembros del grupo se almacenan en el atributo oak: rep:members. El atributo contiene la lista de uid de cada miembro del grupo. Se pueden encontrar detalles adicionales aquí.
Ejemplo:
{
"jcr:primaryType": "rep:Group",
"rep:principalName": "operators",
"rep:managedByIdp": "SAML",
"rep:members": [
"635afa1c-beeb-3262-83c4-38ea31e5549e",
"5e496093-feb6-37e9-a2a1-7c87b1cec4b0",
...
],
...
}
Los grupos externos con pertenencia a grupo dinámico no almacenan ningún miembro en la entrada de grupo.
La pertenencia al grupo se almacena en las entradas de los usuarios. Encontrará documentación adicional aquí. Por ejemplo, este es el nodo de OAK para el grupo:
{
"jcr:primaryType": "rep:Group",
"jcr:mixinTypes": [
"rep:AccessControllable"
],
"jcr:createdBy": "",
"jcr:created": "Tue Jul 16 2024 08:58:47 GMT+0000",
"rep:principalName": "GROUP_1;aem-saml-idp-1",
"rep:lastSynced": "Tue Jul 16 2024 08:58:47 GMT+0000",
"jcr:uuid": "d9c6af8a-35c0-3064-899a-59af55455cd0",
"rep:externalId": "GROUP_1;aem-saml-idp-1",
"rep:authorizableId": "GROUP_1;aem-saml-idp-1"
}
Este es el nodo de un usuario miembro de ese grupo:
{
"jcr:primaryType": "rep:User",
"jcr:mixinTypes": [
"rep:AccessControllable"
],
"surname": "Test",
"rep:principalName": "testUser",
"rep:externalId": "test;aem-saml-idp-1",
"rep:authorizableId": "test",
"rep:externalPrincipalNames": [
"projects-users;aem-saml-idp-1",
"GROUP_2;aem-saml-idp-1",
"GROUP_1;aem-saml-idp-1",
"operators;aem-saml-idp-1"
],
...
}
Habilitación de la pertenencia a grupos dinámicos para usuarios de SAML en entornos existentes
Como se explica en la sección anterior, el formato de los usuarios y grupos externos es ligeramente diferente del utilizado para los usuarios y grupos locales. Es posible definir una nueva ACL para grupos externos y aprovisionar nuevos usuarios externos, o utilizar la herramienta de migración como se describe a continuación.
Habilitar la pertenencia a grupos dinámicos para entornos existentes con usuarios externos
El controlador de autenticación SAML crea usuarios externos cuando se especifica la siguiente propiedad: "identitySyncType": "idp". En este caso, se puede habilitar la pertenencia al grupo dinámico modificando esta propiedad a: "identitySyncType": "idp_dynamic". No se requiere ninguna migración.
Migración automática a la pertenencia a grupos dinámicos para entornos existentes con usuarios locales
El controlador de autenticación SAML crea usuarios locales cuando se especifica la siguiente propiedad: "identitySyncType": "default". También es el valor predeterminado cuando no se especifica la propiedad. En esta sección describimos los pasos que debe seguir el procedimiento de migración automática.
Cuando esta migración está habilitada, se realiza durante la autenticación del usuario y consiste en los siguientes pasos:
- El usuario local se migra a un usuario externo mientras se mantiene el nombre de usuario original. Esto implica que los usuarios locales migrados, que ahora actúan como usuarios externos, conservan su nombre de usuario original en lugar de seguir la sintaxis de nomenclatura mencionada en la sección anterior. Se agregará una propiedad adicional llamada:
rep:externalIdcon el valor de[user name];[idp]. No se modificó el usuarioPrincipalName. - Para cada grupo externo recibido en la aserción SAML, se crea un grupo externo. Si existe un grupo local correspondiente, el grupo externo se agrega al grupo local como miembro.
- El usuario se agrega como miembro del grupo externo.
- A continuación, el usuario local se elimina de todos los grupos locales de Saml a los que era miembro. La propiedad OAK identifica los grupos locales de muestra:
rep:managedByIdp. El controlador de autenticación Saml establece esta propiedad cuando el atributosyncTypeno se especifica o no se establece endefault.
Por ejemplo, si antes de la migración user1 es un usuario local y un miembro del grupo local group1, después de la migración se producirán los siguientes cambios:user1 se convierte en un usuario externo. El atributo rep:externalId se agrega a este perfil.user1 se convierte en miembro del grupo externo: group1;idpuser1 ya no es un miembro directo del grupo local: group1group1;idp es miembro del grupo local: group1.user1 es entonces miembro del grupo local: group1 a través de la herencia
La pertenencia a grupos para grupos externos se almacena en el perfil de usuario de la propiedad rep:externalPrincipalNames
Configuración de la migración automática a la pertenencia a grupos dinámicos
- Habilite la propiedad
"identitySyncType": "idp_dynamic_simplified_id"en el archivo de configuración OSGi de SAML:com.adobe.granite.auth.saml.SamlAuthenticationHandler~...cfg.json: - Configure el nuevo servicio OSGi con el PID de fábrica que comienza por:
com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration~. Por ejemplo, un PID puede ser:com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration~myIdP. Establezca la siguiente propiedad:
{
"idpIdentifier": "<value of IDP Identifier (idpIdentifier)" property from the "com.adobe.granite.auth.saml.SamlAuthenticationHandler" configuration to be migrated>"
}
Para migrar varias configuraciones de SAML, se deben crear varias configuraciones de fábrica de OSGi para com.adobe.granite.auth.saml.migration.SamlDynamicGroupMembershipMigration, cada una de las cuales especifique un idpIdentifier para migrar.
Enlaces SAML personalizados para casos de uso avanzados
Si el IDP no puede enviar los datos de perfil de usuario y la pertenencia al grupo de usuarios en la aserción de SAML, o si los datos deben transformarse antes de la sincronización con AEM, se pueden implementar enlaces de SAML personalizados para ampliar el proceso de autenticación SAML. Los vínculos SAML permiten personalizar la asignación de miembros de grupo, modificar los atributos de perfil de usuario y agregar lógica empresarial personalizada durante el flujo de autenticación.
Cuándo utilizar los enlaces personalizados de SAML
Los ganchos personalizados de SAML son útiles cuando es necesario:
- Asignar dinámicamente miembros de grupo en función de la lógica empresarial personalizada más allá de lo que se proporciona en las afirmaciones de SAML
- Transforme o enriquezca los datos de perfil de usuario antes de sincronizarlos con AEM
- Asignación de estructuras de atributos SAML complejas a propiedades de usuario de AEM
- Implementar reglas de autorización personalizadas o asignaciones de grupos condicionales
- Añadir el registro o la auditoría personalizados durante la autenticación SAML
- Integración con sistemas externos durante el proceso de autenticación
Explicación de la interfaz SamlHook
La interfaz com.adobe.granite.auth.saml.spi.SamlHook proporciona dos métodos de vínculo que se invocan en diferentes etapas del proceso de autenticación SAML:
1. postSamlValidationProcess
Se llama a este método después de validar la respuesta de SAML, pero antes de iniciar el proceso de sincronización de usuarios. Este es el lugar ideal para modificar los datos de aserción de SAML, como añadir o transformar atributos.
public void postSamlValidationProcess(
HttpServletRequest request,
Assertion assertion,
Message samlResponse)
Casos de uso:
- Agregar pertenencias de grupo adicionales a la afirmación
- Transformar valores de atributos antes de sincronizarlos
- Enriquezca la afirmación con datos de fuentes externas
- Validar reglas empresariales personalizadas
2. postSyncUserProcess
Se llama a este método después de que se haya completado el proceso de sincronización de usuarios. Este vínculo se puede utilizar para realizar operaciones adicionales después de crear o actualizar el usuario de AEM.
public void postSyncUserProcess(
HttpServletRequest request,
HttpServletResponse response,
Assertion assertion,
AuthenticationInfo authenticationInfo,
String samlResponse)
Casos de uso:
- Actualizar propiedades adicionales del perfil de usuario no incluidas en la sincronización estándar
- Crear o actualizar recursos personalizados relacionados con el usuario en AEM
- Déclencheur de flujos de trabajo o notificaciones después de la autenticación del usuario
- Registrar eventos de autenticación personalizados
Importante: Para modificar las propiedades de usuario en el repositorio, la implementación del vínculo requiere:
- Referencia de
SlingRepositoryinsertada mediante@Reference - Un usuario de servicio configurado con los permisos apropiados (configurado en "Modificación del servicio de asignador de usuarios del servicio de Apache Sling")
- Administración de sesiones adecuada con bloques try-catch-finally
Implementación de un vínculo SAML personalizado
Los siguientes pasos describen cómo crear e implementar un vínculo SAML personalizado:
Paso 1: Creación de la implementación del vínculo SAML
Cree una nueva clase Java en el proyecto de AEM que implemente la interfaz com.adobe.granite.auth.saml.spi.SamlHook:
package com.mycompany.aem.saml;
import com.adobe.granite.auth.saml.spi.Assertion;
import com.adobe.granite.auth.saml.spi.Attribute;
import com.adobe.granite.auth.saml.spi.Message;
import com.adobe.granite.auth.saml.spi.SamlHook;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.auth.core.spi.AuthenticationInfo;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Designate(ocd = SampleImpl.Configuration.class, factory = true)
public class SampleImpl implements SamlHook {
@ObjectClassDefinition(name = "Saml Sample Authentication Handler Hook Configuration")
@interface Configuration {
@AttributeDefinition(
name = "idpIdentifier",
description = "Identifier of SAML Idp. Match the idpIdentifier property's value configured in the SAML Authentication Handler OSGi factory configuration (com.adobe.granite.auth.saml.SamlAuthenticationHandler~<unique-id>) this SAML hook will hook into"
)
String idpIdentifier();
}
private static final String SAMPLE_SERVICE_NAME = "sample-saml-service";
private static final String CUSTOM_LOGIN_COUNT = "customLoginCount";
private final Logger log = LoggerFactory.getLogger(getClass());
private SlingRepository repository;
@SuppressWarnings("UnusedDeclaration")
@Reference(name = "repository", cardinality = ReferenceCardinality.MANDATORY)
public void bindRepository(SlingRepository repository) {
this.repository = repository;
}
/**
* This method is called after the user sync process is completed.
* At this point, the user has already been synchronized in OAK (created or updated).
* Example: Track login count by adding custom attributes to the user in the repository
*
* @param request
* @param response
* @param assertion
* @param authenticationInfo
* @param samlResponse
*/
@Override
public void postSyncUserProcess(HttpServletRequest request, HttpServletResponse response, Assertion assertion,
AuthenticationInfo authenticationInfo, String samlResponse) {
log.info("Custom Audit Log: user {} successfully logged in", authenticationInfo.getUser());
// This code executes AFTER the user has been synchronized in OAK
// The user object already exists in the repository at this point
Session serviceSession = null;
try {
// Get a service session - requires "sample-saml-service" to be configured as system user
// Configure in: "Apache Sling Service User Mapper Service Amendment"
serviceSession = repository.loginService(SAMPLE_SERVICE_NAME, null);
// Get the UserManager to work with users and groups
UserManager userManager = ((JackrabbitSession) serviceSession).getUserManager();
// Get the authorizable (user) that just logged in
Authorizable user = userManager.getAuthorizable(authenticationInfo.getUser());
if (user != null && !user.isGroup()) {
ValueFactory valueFactory = serviceSession.getValueFactory();
// Increment login count
long loginCount = 1;
if (user.hasProperty(CUSTOM_LOGIN_COUNT)) {
loginCount = user.getProperty(CUSTOM_LOGIN_COUNT)[0].getLong() + 1;
}
user.setProperty(CUSTOM_LOGIN_COUNT, valueFactory.createValue(loginCount));
log.debug("Set {} property to {} for user {}", CUSTOM_LOGIN_COUNT, loginCount, user.getID());
// Save all changes to the repository
if (serviceSession.hasPendingChanges()) {
serviceSession.save();
log.debug("Successfully saved custom attributes for user {}", user.getID());
}
} else {
log.warn("User {} not found or is a group", authenticationInfo.getUser());
}
} catch (RepositoryException e) {
log.error("Error adding custom attributes to user repository for user: {}",
authenticationInfo.getUser(), e);
} finally {
if (serviceSession != null) {
serviceSession.logout();
}
}
}
/**
* This method is called after the SAML response is validated but before the user sync process starts.
* We can modify the assertion here to add custom attributes.
*
* @param request
* @param assertion
* @param samlResponse
*/
@Override
public void postSamlValidationProcess(@Nonnull HttpServletRequest request, @Nonnull Assertion assertion, @Nonnull Message samlResponse) {
// Add the attribute "memberOf" with value "sample-group" to the assertion
// In this example "memberOf" is a multi-valued attribute that contains the groups from the Saml Idp
log.debug("Inside postSamlValidationProcess");
Attribute groupsAttr = assertion.getAttributes().get("groups");
if (groupsAttr != null) {
groupsAttr.addAttributeValue("sample-group-from-hook");
} else {
groupsAttr = new Attribute();
groupsAttr.setName("groups");
groupsAttr.addAttributeValue("sample-group-from-hook");
assertion.getAttributes().put("groups", groupsAttr);
}
}
}
Paso 2: Configuración del vínculo de SAML
El vínculo SAML utiliza la configuración OSGi para especificar a qué IDP debe aplicarse. Cree un archivo de configuración OSGi en el proyecto en:
/ui.config/src/main/content/jcr_root/wknd-examples/osgiconfig/config.publish/com.mycompany.aem.saml.CustomSamlHook~okta.cfg.json
{
"idpIdentifier": "$[env:SAML_IDP_ID;default=http://www.okta.com/exk4z55r44Jz9C6am5d7]",
"service.ranking": 100
}
El idpIdentifier debe coincidir con el valor idpIdentifier configurado en la configuración de fábrica correspondiente de OSGi del controlador de autenticación SAML (PID: com.adobe.granite.auth.saml.SamlAuthenticationHandler~<unique-id>.cfg.json). Esta coincidencia es crítica: el vínculo SAML solo se invocará para la instancia del controlador de autenticación SAML que tenga el mismo valor idpIdentifier. El controlador de autenticación SAML es una configuración de fábrica, lo que significa que puede tener varias instancias (por ejemplo, com.adobe.granite.auth.saml.SamlAuthenticationHandler~okta.cfg.json, com.adobe.granite.auth.saml.SamlAuthenticationHandler~azure.cfg.json) y cada vínculo está vinculado a un controlador específico a través de idpIdentifier. La propiedad service.ranking controla el orden de ejecución cuando se configuran varios vínculos (los valores más altos se ejecutan primero).
Paso 3: Añadir dependencias de Maven
Agregue la dependencia SAML SPI necesaria al pom.xml del proyecto principal de AEM Maven.
Para proyectos de AEM as a Cloud Service, use la dependencia de la API de AEM SDK que incluye las interfaces de SAML:
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>aem-sdk-api</artifactId>
<version>${aem.sdk.api}</version>
<scope>provided</scope>
</dependency>
El artefacto aem-sdk-api contiene todas las interfaces SAML de Adobe Granite necesarias, incluida com.adobe.granite.auth.saml.spi.SamlHook.
Paso 4: Configurar el usuario de servicio (si se modifica el repositorio)
Si el vínculo de SAML necesita modificar las propiedades del usuario en el repositorio (como se muestra en el ejemplo postSyncUserProcess), se debe configurar un usuario de servicio:
- Cree una asignación de usuario de servicio en el proyecto en
/ui.config/src/main/content/jcr_root/apps/myproject/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~saml.cfg.json:
{
"user.mapping": [
"com.mycompany.aem.core:sample-saml-service=saml-hook-service"
]
}
- Cree un script de repoinit para definir el usuario del servicio y los permisos en
/ui.config/src/main/content/jcr_root/apps/myproject/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer~saml.cfg.json:
create service user saml-hook-service with path system/saml
set ACL for saml-hook-service
allow jcr:read,rep:write,rep:userManagement on /home/users
end
Esto otorga al servicio permisos de usuario para leer y modificar las propiedades de usuario en el repositorio.
Paso 5: Implementación en AEM
Implemente el vínculo personalizado SAML en AEM as a Cloud Service:
- Creación del proyecto de AEM
- Transfiera el código al repositorio de Git de Cloud Manager
- Implementar mediante una canalización de implementación de pila completa
- El vínculo de SAML se activará automáticamente cuando un usuario se autentique mediante SAML
Consideraciones importantes
- Identificador de IDP que coincide: El
idpIdentifierconfigurado en el vínculo de SAML debe coincidir exactamente con elidpIdentifierde la configuración de fábrica del controlador de autenticación SAML (com.adobe.granite.auth.saml.SamlAuthenticationHandler~<unique-id>) - Nombres de atributos: Asegúrese de que los nombres de atributos a los que se hace referencia en el vínculo (por ejemplo,
groupMembership) coincidan con los atributos configurados en el Controlador de autenticación SAML - Rendimiento: Mantenga las implementaciones de gancho ligeras a medida que se ejecutan durante cada autenticación SAML
- Tratamiento de errores: las implementaciones de ganchos de SAML deberían generar
com.adobe.granite.auth.saml.spi.SamlHookExceptioncuando se produzcan errores críticos que no superen la autenticación. El controlador de autenticación SAML detectará estas excepciones y devolveráAuthenticationInfo.FAIL_AUTH. Para las operaciones del repositorio, capture siempreRepositoryExceptiony registre correctamente los errores. Utilice bloques try-catch-finally para garantizar una limpieza adecuada de los recursos - Pruebas: Pruebe exhaustivamente los vínculos personalizados en entornos inferiores antes de implementarlos en producción
- Varios enlaces: Se pueden configurar varias implementaciones de enlaces de SAML; se ejecutarán todos los enlaces coincidentes. Utilice la propiedad
service.rankingen el componente OSGi para controlar el orden de ejecución (los valores de mayor clasificación se ejecutan primero). Para reutilizar un vínculo de SAML en varias configuraciones de fábrica del controlador de autenticación SAML (com.adobe.granite.auth.saml.SamlAuthenticationHandler~<unique-id>), cree varias configuraciones de vínculo (configuraciones de fábrica OSGi), cada una con unidpIdentifierdiferente que coincida con el controlador de autenticación SAML correspondiente - Seguridad: valide y sanee todos los datos de las aserciones de SAML antes de usarlos en la lógica empresarial
- Acceso al repositorio: Al modificar las propiedades del usuario en
postSyncUserProcess, use siempre un usuario de servicio con los permisos apropiados en lugar de sesiones administrativas - Permisos de usuario de servicio: Conceda los permisos mínimos necesarios al usuario de servicio (por ejemplo, solo
jcr:readyrep:writeen/home/users, no derechos de administrador completos) - Administración de sesiones: Use siempre bloques try-catch-finally para asegurarse de que las sesiones del repositorio se cierren correctamente, incluso si se producen excepciones
- Sincronización del usuario: el vínculo
postSyncUserProcessse ejecuta después de sincronizar el usuario con OAK, por lo que se garantiza que el objeto de usuario existe en el repositorio en ese momento
Implementación de la configuración SAML
Las configuraciones de OSGi deben enviarse a Git e implementarse en AEM as a Cloud Service mediante Cloud Manager.
$ git remote -v
adobe https://git.cloudmanager.adobe.com/myOrg/myCloudManagerGit/ (fetch)
adobe https://git.cloudmanager.adobe.com/myOrg/myCloudManagerGit/ (push)
$ git add .
$ git commit -m "SAML 2.0 configurations"
$ git push adobe saml-auth:develop
Implemente la rama de Git de Cloud Manager de destino (en este ejemplo, develop) mediante una canalización de implementación de pila completa.
Invocación de la autenticación SAML
El flujo de autenticación SAML se puede invocar desde una página web del sitio de AEM, creando vínculos especialmente diseñados o botones. Los parámetros que se describen a continuación se pueden configurar mediante programación según sea necesario, por ejemplo, un botón de inicio de sesión puede establecer saml_request_path, que es donde se lleva al usuario tras la autenticación SAML correcta, en diferentes páginas de AEM, según el contexto del botón.
Almacenamiento en caché seguro mientras se usa SAML
En la instancia de publicación de AEM, la mayoría de las páginas se almacenan generalmente en caché. Sin embargo, para las rutas protegidas con SAML, el almacenamiento en caché debe deshabilitarse o el almacenamiento en caché seguro debe habilitarse mediante la configuración auth_checker. Para obtener más información, consulte los detalles proporcionados aquí
Tenga en cuenta que si almacena en caché rutas protegidas sin habilitar el auth_checker, puede experimentar un comportamiento impredecible.
petición GET
La autenticación SAML se puede invocar creando una petición HTTP GET con el formato:
HTTP GET /system/sling/login
y proporcionando parámetros de consulta:
resourcepath.saml_request_pathPor ejemplo, este vínculo de HTML almacenará en déclencheur el flujo de inicio de sesión de SAML y, una vez realizado correctamente, llevará al usuario a /content/wknd/us/en/protected/page.html. Estos parámetros de consulta se pueden configurar mediante programación según sea necesario.
<a href="/system/sling/login?resource=/content/wknd&saml_request_path=/content/wknd/us/en/protected/page.html">
Log in using SAML
</a>
petición POST
La autenticación SAML se puede invocar creando una solicitud HTTP POST con el formato:
HTTP POST /system/sling/login
y proporcionar los datos del formulario:
resourcepath.saml_request_pathPor ejemplo, este botón de HTML utilizará un POST HTTP para almacenar en déclencheur el flujo de inicio de sesión de SAML y, una vez realizado correctamente, llevar al usuario a /content/wknd/us/en/protected/page.html. Estos parámetros de datos de formulario se pueden definir mediante programación según sea necesario.
<form action="/system/sling/login" method="POST">
<input type="hidden" name="resource" value="/content/wknd">
<input type="hidden" name="saml_request_path" value="/content/wknd/us/en/protected/page.html">
<input type="submit" value="Log in using SAML">
</form>
Configuración de Dispatcher
Tanto el método HTTP GET como el método POST requieren acceso de cliente a los extremos /system/sling/login de AEM y, por lo tanto, se deben permitir a través de AEM Dispatcher.
Permitir los patrones de URL necesarios en función de si se utiliza GET o POST
# Allow GET-based SAML authentication invocation
/0191 { /type "allow" /method "GET" /url "/system/sling/login" /query "*" }
# Allow POST-based SAML authentication invocation
/0192 { /type "allow" /method "POST" /url "/system/sling/login" }