Preamble
To handle a SAML authentication in Adelia Studio's REST APIs, you must declare the following elements in the Beans.xml file of the web application:
- A SAML handler corresponding to the location/format of the SAML assertion in the HTTP request:
- RsSamlHeaderInHandler for an assertion passed in the HTTP header (Authorization)
Example:
Http-Method: GET
Headers: {Accept=[application/xml], Authorization=[SAML eJydV1mTokgQfu9fYTCPrs2htGKMHVEcKq2gKOLxsoFQAsqhFAjNr99CW1ud7t2ZjdA...], ...}
- RsSamlEnvelopedInHandler for an assertion passed in the body of the HTTP request with an application/xml media type, assertion included in an
<env:Envelope xmlns:env="http://org.apache.cxf/rs/env">
element.
Example:
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 for an assertion passed in the HTTP request code in the form of an HTTP form, application/x-www-form-urlencoded media type.
Example:
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 for an assertion passed in the HTTP header (Authorization)
- A SamlAuthentConfiguration element to declare the URLs requiring authentication.
- The security.signature.properties property for the service access point (jaxrs:server) enabling the keystore containing the public key able to validate the assertion's signature to be addressed.
Configuration
RsSamlHeaderInHandler | RsSamlEnvelopedInHandler | RsSamlFormInHandler
RsSamlHeaderInHandler : This element is used to declare SAML authentication via the Authorization HTTP header.
<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlHeaderInHandler"/>
RsSamlEnvelopedInHandler : This element is used to declare SAML authentication via an envelope in the payload of an HTTP request (POST | PUT).
Request media type: application/xml<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlEnvelopedInHandler"/>
RsSamlFormInHandler : This element is used to declare SAML authentication via a form in the payload of an HTTP request (POST | PUT).
Request media type: application/x-www-form-urlencoded
Form type Adelia input parameters: PARAM p1,I,[form('attrname1)] p2,I[form('attrname2)]...<bean id="samlEnvHandler" class="com.hardis.adelia.webservice.RSSamlFormInHandler"/>
Note: if it becomes necessary to modify the creation rules for the SecurityContext object from the SAML assertion (authenticated user's name, user's roles), a class deriving from the org.apache.cxf.rs.security.saml.authorization.SecurityContextProviderImpl class can be referenced using the property called SecurityContextProvider.
<bean id="samlHeaderInHandler" class="com.hardis.adelia.webservice.RSSamlHeaderInHandler"> <property name="securityContextProvider"> <bean class="com.hardis.adelia.webservice.RsSamlSecurityContextProvider"/> </property> </bean>
SamlAuthentConfiguration
This element is used to define:- the scheme used (SAML by default),
- the URIs for which authentication is required,
- the need for a secure transport layer,
a passthrough for swagger (i.e. swagger access URI, for which authentication is not required).
<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*"/> </bean>
Validating the SAML assertion signature
The properties required to validate the assertion signature need to be entered at jaxrs:server element level
<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>
Notes: other properties of the CXF framework may be added to, for example, request audience validation, choose a specific SAML assertion element to retrieve the roles of the authenticated user, etc.
These properties are described here: http://cxf.apache.org/docs/security-configuration.html.
The referenced saml.properties file (used to declare the WSS4J properties) must be placed in the application's /WEB-INF/Classes directory, observing any package organization, and must contain the following entries:
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
Notes:
- The keystore.jks keystore must be placed in the application's /WEB-INF/Classes directory, observing and package organization.
- The alias and password providing access to the keystore need to be specified (alias and password in the example).
- The keystore contains the public key used to validate the SAML assertion signature.
All the WSS4J properties are described here: https://ws.apache.org/wss4j/config.html. ↑ Top of page