Préambule
Pour prendre en charge une authentification SAML dans les Apis REST d'Adélia Studio, vous devez déclarer les éléments suivants dans le fichier Beans.xml de l'application web :
- Un handler SAML correspondant à l'emplacement/forme de l'assertion SAML dans la requête HTTP :
- RsSamlHeaderInHandler pour une assertion passée dans le header HTTP (Authorization)
Exemple :
Http-Method: GET
Headers: {Accept=[application/xml], Authorization=[SAML eJydV1mTokgQfu9fYTCPrs2htGKMHVEcKq2gKOLxsoFQAsqhFAjNr99CW1ud7t2ZjdA...], ...}
- RsSamlEnvelopedInHandler pour une assertion passée dans le corps de la requête HTTP avec un media type application/xml, assertion incluse dans un élément
<env:Envelope xmlns:env="http://org.apache.cxf/rs/env">
Exemple :
Http-Method: POST
Content-Type: application/xml
Payload:
<env:Envelope xmlns:env="http://org.apache.cxf/rs/env"ID="e795cdd1-c19d-4a5c-8d86-e8a781af4787">
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
...
</saml2:Assertion>
<payload...>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...</ds:Signature>
</env:Envelope>
RsSamlFormInHandler pour une assertion passée dans le code de la requête HTTP sous la forme d'un formulaire HTTP, media type application/x-www-form-urlencoded.
Exemple:
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
Headers: {Accept=[application/xml], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[2206], content-type=[application/x-www-form-urlencoded],
Host=[localhost:9000], Pragma=[no-cache], User-Agent=[Apache CXF ${project.version}]}
Payload: nom=DUPONT&age=48&SAMLToken=eJydV1tzqkgQfs+vsDiPWcNFjWIdUzUIGqJgQMTLyxYOI6BclAFBfv0OGo16kt1ztk...
- RsSamlHeaderInHandler pour une assertion passée dans le header HTTP (Authorization)
- Un élément SamlAuthentConfiguration pour déclarer les URL requérant l'authentification.
- La propriété security.signature.properties pour le point d'accès des services (jaxrs:server) permettant d'adresser le keystore contenant la clé publique capable de valider la signature de l'assertion.
Configuration
RsSamlHeaderInHandler | RsSamlEnvelopedInHandler | RsSamlFormInHandler
RsSamlHeaderInHandler : Cet élément permet de déclarer une authentification SAML via le header HTTP Authorization.
<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlHeaderInHandler"/>
RsSamlEnvelopedInHandler : Cet élément permet de déclarer une authentification SAML via une enveloppe dans le payload d'une requête HTTP (POST | PUT).
Media type de la requête : application/xml<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlEnvelopedInHandler"/>
RsSamlFormInHandler : Ccet élément permet de déclarer une authentification SAML via un formulaire dans le payload d'une requête HTTP (POST | PUT).
Media type de la requête : application/x-www-form-urlencoded
Paramètres Adélia en entrée de nature form : PARAM p1,I,[form('nomattr1)] p2,I[form('nomattr2)]...<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlFormInHandler"/>
Remarque : s'il s'avère nécessaire de modifier les règles de création de l'objet SecurityContext issu de l'assertion SAML (nom de l'utilisateur authentifié, rôles de l'utilisateur) alors il est possible de référencer une classe dérivant de la classe org.apache.cxf.rs.security.saml.authorization.SecurityContextProviderImpl, à l'aide de la propriété nommée SecurityContextProvider.
<bean id="samlHeaderInHandler" class="com.hardis.adelia.webservice.RSSamlHeaderInHandler"> <property name="securityContextProvider"> <bean class="com.hardis.adelia.webservice.RsSamlSecurityContextProvider"/> </property> </bean>
SamlAuthentConfiguration
Cet élément permet de définir :- le scheme utilisé (SAML par défaut),
- les URI pour lesquelles l'authentification est requise,
- la nécessité d'une couche transport sécurisé,
un "passthrough" (laissez-passer) pour swagger (i.e. URI d'accès à swagger, pour lesquelles l'authentification n'est pas requise).
<bean id="samlHeaderConfiguration" class="com.hardis.adelia.webservice.SamlAuthentConfiguration"> <property name="samlAuthScheme" value="SAML"/> <property name="samlBasePath" value="/ws/*"/> <property name="samlConfidential" value="false"/> <property name="samlSwaggerURI" value="/ws/api-docs;/ws/swagger*;/ws/openapi*"/> </bean>
Validation de la signature de l'assertion SAML
Les propriétés nécessaires à la validation de la signature de l'assertion sont à renseigner au niveau de l'élément jaxrs:server
<jaxrs:server id="rest" address="/" transportId="http://cxf.apache.org/transports/http"> ... <jaxrs:properties> <entry key="security.signature.properties" value="saml/jaxrsclient/saml.properties"/> </jaxrs:properties> ... </jaxrs:server>
Remarques : d'autres propriétés du framework CXF peuvent être ajoutées pour, par exemple, demander la validation de l'audience, choisir un élément particulier de l'assertion SAML pour récupérer les rôles de l'utilisateur authentifié, etc.
Ces propriétés sont décrites ici : http://cxf.apache.org/docs/security-configuration.html.
Le fichier saml.properties référencé (utilisé pour déclarer les propriétés WSS4J) doit être placé dans le répertoire /WEB-INF/Classes de l'application, en respectant le package éventuel, et doit contenir les entrées suivantes :
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.alias=alias org.apache.ws.security.crypto.merlin.keystore.password=password org.apache.ws.security.crypto.merlin.keystore.file=keys/saml.jks
Remarques :
- Le keystore keystore.jks doit être placé dans le répertoire /WEB-INF/Classes de l'application, en respectant le package éventuel.
- Il faut préciser l'alias et le mot de passe permettant d'accéder au keystore (alias et password dans l'exemple).
- Le keystore contient la clé publique permettant de valider la signature de l'assertion SAML.
Toutes les propriété WSS4J sont décrites ici : https://ws.apache.org/wss4j/config.html. ↑ Haut de page