Configure ELM Authentication with Multiple SAML Identity Providers
Authors: ShubjitNaikBuild basis: Engineering Lifecycle Management / Jazz Authorization Server 7.0.2 or higher
Page contents
- Configuration Options
- Deployment Overview
- Configure JAS and User Group Role Mapping
- Create a new Liberty Server for SAML Configurations
- Enable Redirection in JAS to multiple SAML IDPs
- Test the Deployment
- Reverse Proxy - IBM HTTP Server Plugin Configuration
- Configure Local Authentication along with SAML Identity Provider
There are requirements where ELM has to be deployed in an environment for users from different companies to collaborate. And in this scenario the end users would need to authenticate against different SAML IDPs which could be their respective company owned IDPs. Can we configure multiple Identity Providers with IBM Engineering Lifecycle Management Solution?
You can setup ELM to authenticate via Jazz Authorization Server (JAS) which is based on WebSphere Liberty. And using the SamlWeb 2.0 feature Liberty can be configured to further delegate the user authentication to a Third Party SAML IdP. When JAS is configured with multiple OIDC Providers, Liberty presents a Social Media Selection Form to pick from a list of configured Providers. Although when configured with Multiple SAML IdPs a similar list is not available, we can depend on AuthFilters or we can modify the deployment to include another Liberty server and create unique filters to configure Authentication against Multiple SAML IdPs, and this is the focus of the article.
Sample Deployment
You can setup ELM to authenticate via Jazz Authorization Server (JAS) which is based on WebSphere Liberty. And using the SamlWeb 2.0 feature Liberty can be configured to further delegate the user authentication to a Third Party SAML IdP. When JAS is configured with multiple OIDC Providers, Liberty presents a Social Media Selection Form to pick from a list of configured Providers. Although when configured with Multiple SAML IdPs a similar list is not available, we can depend on AuthFilters or we can modify the deployment to include another Liberty server and create unique filters to configure Authentication against Multiple SAML IdPs, and this is the focus of the article.
Configuration Options
There are two Use Cases for configuring JAS with multiple SAML IdPs-
Use Case 1: Utilize Liberty SAML config AuthFilters to redirect to multiple SAML IdPs
-
Use Case 2: When none of the available AuthFilters works for your deployment, install an additional Liberty server- The rest of the article targets
Use Case 2
- The rest of the article targets
Deployment Overview
The high level instructions to configure ELM with SAML IdPs:- Configure JAS with multiple LDAP servers via SCIM or with one consolidated LDAP server (LDAP server should replicate ELM users from all SAML IdPs)
- Configure CA Certificates for JAS
- Setup ELM with JAS or Migrate and existing setup from container authentication to JAS
- Configure JAS to redirect to Multiple OIDC Providers
- Create a new Liberty server and configure
- Multiple OIDC Providers (OP1 and OP2)
- Multiple SAML Configurations (samlSP1 and samlSP2)
- Configure SAML AuthFilters to match incoming URL patterns from JAS
- Export SP Metadata for each SAML config
- Import SAML IdP metadata from each IDP
- Configure ELM Authentication with a Third Party OIDC provider
- Configure ELM Authentication with a SAML Identity Provider.
Sample Deployment
Limitations
- Logout from ELM applications does not work
Configure JAS and User Group Role Mapping
First step is to configure ELM and JAS. You would need to either configure JAS with multiple LDAPs, one each for a SAML IDP, or a consolidated LDAP server which has a copy of all the Users from multiple SAML IDPs.- To configure multiple LDAPs in JAS you would need to enable SCIM. Visit Configure Multiple User Registries with JAS and SCIM
- To configure a single LDAP with JAS Visit Configure JAS with an LDAP User Registry
- When configured with SCIM, JTS does the group lookup via the SCIM URL and groups provided under JTS Admin > Advanced Properties >
-
com.ibm.team.repository.service.jts.internal.userregistry.scim.SCIMUserRegistryProviderfor User group to Jazz role mappings
-
- When configured with LDAP, JTS does a group lookup via an ldapsearch Query against the LDAP and group details mentioned under JTS Admin > Advanced Properties >
-
com.ibm.team.repository.service.jts.internal.userregistry.ldap.LDAPUserRegistryProviderfor User group to Jazz role mappings.
-
Create a new Liberty Server for SAML Configurations
Create a new Liberty Server using the JAS installation on port9644 for Multiple OpenId Connect Providers and SAML Configurations.
Create server
The following examples uses JAS to create another server and copy over LDAP and SSL keystore files- Create a new liberty Server on Jazz Authorization Server
-
cd [JAS_HOME]/wlp/bin -
./server create samlop
-
- Copy LDAP configuration from jazzop to samlop
-
cd [JAS_HOME]/wlp/usr/servers/samlop -
mkdir defaults -
cp ../jazzop/defaults/ldapUserRegistry.xml defaults/
-
- Copy the ssl keystore from jazzop to samlop
-
cd [JAS_HOME]/wlp/usr/servers/samlop -
cp ../jazzop/ibm-team.keystore .
-
- Update JVM Config , create a file
jvm.optionsand set heap to 4GB-
cd [JAS_HOME]/wlp/usr/servers/samlop -
vi jvm.options -
-Xmx4G -Xms4G -Xmn1G
-
Update features, Port and SSL configurations
Change directory to[JAS_HOME]/wlp/usr/servers/samlop and edit server.xml (delete old content). Enable features, LDAP, SSL configurations and set port to 9644
<?xml version="1.0" encoding="UTF-8"?>
<server description="SAML_OP">
<featureManager>
<feature>openidConnectServer-1.0</feature>
<feature>appSecurity-2.0</feature>
<feature>ldapRegistry-3.0</feature>
<feature>ssl-1.0</feature>
<feature>samlWeb-2.0</feature>
</featureManager>
<httpEndpoint host="*" httpPort="9281" httpsPort="9644" id="defaultHttpEndpoint"/>
<keyStore
id="defaultKeyStore"
location="ibm-team.keystore"
type="JCEKS"
password="{xor}Nj0ycis6PjI="/>
<ssl id="defaultSSLConfig"
keyStoreRef="defaultKeyStore"
trustStoreRef="defaultKeyStore"
serverKeyAlias="sslkey"
clientAuthenticationSupported="false"/>
<include location="ldapUserRegistry.xml" optional="true"/>
<!-- To grant all authenticated users access to the OIDC protected resource, grant them the oauth-role authenticated -->
<oauth-roles>
<authenticated>
<special-subject type="ALL_AUTHENTICATED_USERS"/>
</authenticated>
<clientManager>
<group name="JazzAdmins" />
</clientManager>
</oauth-roles>
</server>
Create openidConnectProvider configurations
Appendserver.xml file, create a openidConnectProvider config for each SAML IDP. Following is an example for 2 SAML IdPs
<openidConnectProvider id="op1" oauthProviderRef="oauth1" sessionManaged="true" signatureAlgorithm="RS256" />
<oauthProvider id="oauth1" >
<localStore>
<client name="SamlClientID_1" secret="SamlPassword_1" displayname="OpenID Provider SAML1"
scope="openid profile email general" preAuthorizedScope="openid profile email general"
redirect="https://<Jazz_Auth_server>/ibm/api/social-login/redirect/samlop1"
/>
</localStore>
</oauthProvider>
<openidConnectProvider id="op2" oauthProviderRef="oauth2" sessionManaged="true" signatureAlgorithm="RS256" />
<oauthProvider id="oauth2" >
<localStore>
<client name="SamlClientID_2" secret="SamlPassword_2" displayname="OpenID Provider SAML2"
scope="openid profile email general" preAuthorizedScope="openid profile email general"
redirect="https://<Jazz_Auth_server>/ibm/api/social-login/redirect/samlop2"
/>
</localStore>
</oauthProvider>
-
idandoauthProviderRefare unique per OpenId Provider configuration - Client
name,secretandredirectURL ID will be used in the Social Login config on JAS
Create Multiple SAML configurations
Import each SAML IDP metadata by copying it to[JAS_HOME]/wlp/usr/servers/samlop/resources/security
Append server.xml file, configure multiple SAML IdP redirect configurations and set AuthFilters to incoming JAS URLs based on the id created in the previous step. Following is an example for 2 SAML configurations.
<samlWebSso20 id="defaultSP" enabled="false" > </samlWebSso20>
<samlWebSso20 id="samlSP1"
spCookieName="jazzop_sso_cookie_idp_1"
forceAuthn="true"
idpMetadata="[JAS_HOME]/wlp/usr/servers/samlop/resources/security/samlidp1.xml"
keyStoreRef="defaultKeyStore"
keyAlias="sslkey"
enabled="true"
authFilterRef="samlAuthFilter1" >
</samlWebSso20>
<authFilter id="samlAuthFilter1">
<requestUrl id="samlRequestUrl" urlPattern="/op1/authorize" matchType="contains" />
</authFilter>
<samlWebSso20 id="samlSP2"
spCookieName="jazzop_sso_cookie_idp_2"
forceAuthn="true"
idpMetadata="[JAS_HOME]/wlp/usr/servers/samlop/resources/security/samlidp2.xml"
keyStoreRef="defaultKeyStore"
keyAlias="sslkey"
enabled="true"
authFilterRef="samlAuthFilter2" >
</samlWebSso20>
<authFilter id="samlAuthFilter2">
<requestUrl id="samlRequestUrl" urlPattern="/op2/authorize" matchType="contains" />
</authFilter>
-
op1andop2used inurlPatternare the =id='s created in the openidConnectProvider configuration
Export multiple SP metadata
Start the Liberty Server using the command[JAS_HOME}/start-jazz
Export SP metadata to be shared with each SAML IDP. samlSP1 and samlSP2 are IDs created in the samlWebSso20 config.
- Download samlSP1 metadata -
https://[Jazz_Auth_Server]:9644/ibm/saml20/samlSP1/samlmetadata - Download samlSP2 metadata -
https://[Jazz_Auth_Server]:9644/ibm/saml20/samlSP2/samlmetadata
Test Multiple SAML IDP redirection
In the Endpoint URLs belowop1 and op2 are ids created in the openidConnectProvider configuration. Test by accessing the following URLs, if they are redirected to a different SAML Idp
- SAML IDP 1 access URL -
https://[Jazz_Auth_server]:9644/oidc/endpoint/op1/authorize - SAML IDP 2 access URL -
https://[Jazz_Auth_server]:9644/oidc/endpoint/op2/authorize
Enable Redirection in JAS to multiple SAML IDPs
Now that a Liberty Server is configured with multiple SAML configurations and also multiple OpenId Connect Providers (OP), we will redirect JAS to each OP by configure multiple Social Login configurations, creating anoidcLogin config for each OP configured in the new liberty server
- Change directory to =[JAS_HOME]/wlp/usr/servers/jazzop
- Edit
server.xmlfile and add the following features withinfeatureManager<feature>socialLogin-1.0</feature> <feature>appSecurity-2.0</feature>
- If you have the
samlWeb-2.0feature enabled on JAS, it can be disabled
- Edit appConfig.xml and add the following configurations
<!-- Social Login Configuration to redirect to Liberty server configured with Multiple IDPs --> <oidcLogin id="samlop1" displayName="SAML IDP A" clientId="SamlClientID_1" clientSecret="SamlPassword_1" discoveryEndpoint="https://<Jazz_Auth_server>:9644/oidc/endpoint/op1/.well-known/openid-configuration" scope="openid profile email general" userNameAttribute="sub" trustStoreRef="defaultKeyStore" authFilterRef="OPAuthFilter1" mapToUserRegistry="true" > </oidcLogin> <authFilter id="OPAuthFilter1"> <requestUrl id="OPRequestUrl1" urlPattern="/authorize" matchType="contains" /> <userAgent id="OPUserAgent1" agent="Mozilla|Opera" matchType="contains"/> </authFilter> <oidcLogin id="samlop2" displayName="SAML IDP B" clientId="SamlClientID_2" clientSecret="SamlPassword_2" discoveryEndpoint="https://<Jazz_Auth_server>:9644/oidc/endpoint/op2/.well-known/openid-configuration" scope="openid profile email general" userNameAttribute="sub" trustStoreRef="defaultKeyStore" authFilterRef="OPAuthFilter2" mapToUserRegistry="true" > </oidcLogin> <authFilter id="OPAuthFilter2"> <requestUrl id="OPRequestUrl2" urlPattern="/authorize" matchType="contains" /> <userAgent id="OPUserAgent2" agent="Mozilla|Opera" matchType="contains"/> </authFilter>
-
idis picked from the OPredirectURL configured in Liberty server, example /samlop1 -
clientIdandclientSecretis picked fromnameandsecret parameters from =oauthProvideron the Liberty Server -
displayNameis the name shown on the Liberty Social Media Selection form
discoveryEndpoint URLs with the Reverse Proxy URLs.
Test the Deployment
The Liberty server start and stop would be in parallel with JAS (jazzop starts first followed by samlop). - Start -
[JAS_HOME}/start-jazz - Stop -
[JAS_HOME}/stop-jazz
Reverse Proxy - IBM HTTP Server Plugin Configuration
Here is an example of a merged plugin config for IBM HTTP Server<!-- Jazz Authorization Server - jazzop -->
<VirtualHostGroup Name="default_host_jazzop">
<VirtualHost Name="*:80"/>
<VirtualHost Name="*:443"/>
</VirtualHostGroup>
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="jazzop_default_node_Cluster" PostBufferSize="0" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
<Server CloneID="609d6ec4-46b5-4652-a377-76e8a1d0743c" ConnectTimeout="5" ExtendedHandshake="false" LoadBalanceWeight="20" MaxConnections="-1" Name="default_node_jazzop" ServerIOTimeout="900" WaitForContinue="false">
<Transport Hostname="[JAS_IP]" Port="9280" Protocol="http"/>
<Transport Hostname="[JAS_IP]" Port="9643" Protocol="https">
<Property Name="keyring" Value="/opt/IBM/WebSphere/Plugins/config/webserver1/plugin-key.kdb"/>
<Property Name="stashfile" Value="/opt/IBM/WebSphere/Plugins/config/webserver1/plugin-key.sth"/>
</Transport>
</Server>
<PrimaryServers>
<Server Name="default_node_jazzop"/>
</PrimaryServers>
</ServerCluster>
<UriGroup Name="default_host_jazzop_default_node_Cluster_URIs">
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/jazzop/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/oidc/endpoint/jazzop/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/ibm/api/social-login/*"/>
</UriGroup>
<Route ServerCluster="jazzop_default_node_Cluster" UriGroup="default_host_jazzop_default_node_Cluster_URIs" VirtualHostGroup="default_host_jazzop"/>
<!-- Jazz Authorization Server - New Liberty Server /samlop -->
<VirtualHostGroup Name="default_host_samlop">
<VirtualHost Name="*:80"/>
<VirtualHost Name="*:443"/>
</VirtualHostGroup>
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="samlop_default_node_Cluster" PostBufferSize="0" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
<Server CloneID="26d51d70-2025-4aed-8822-cdff0f1d93bd" ConnectTimeout="5" ExtendedHandshake="false" LoadBalanceWeight="20" MaxConnections="-1" Name="default_node_samlop" ServerIOTimeout="900" WaitForContinue="false">
<Transport Hostname="[JAS_IP]" Port="9281" Protocol="http"/>
<Transport Hostname="[JAS_IP]" Port="9644" Protocol="https">
<Property Name="keyring" Value="/opt/IBM/WebSphere/Plugins/config/webserver1/plugin-key.kdb"/>
<Property Name="stashfile" Value="/opt/IBM/WebSphere/Plugins/config/webserver1/plugin-key.sth"/>
</Transport>
</Server>
<PrimaryServers>
<Server Name="default_node_samlop"/>
</PrimaryServers>
</ServerCluster>
<UriGroup Name="default_host_samlop_default_node_Cluster_URIs">
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/samlop/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/oidc/endpoint/samlop/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/oidc/endpoint/op1/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/oidc/endpoint/op2/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/ibm/saml20/*"/>
</UriGroup>
<Route ServerCluster="samlop_default_node_Cluster" UriGroup="default_host_samlop_default_node_Cluster_URIs" VirtualHostGroup="default_host_samlop"/>
Configure Local Authentication along with SAML Identity Provider
You can configure Socal Login Web Application to include Local Authentication in the Selection form. Add the following configuration along with all theoidcLogin configurations:
<socialLoginWebapp enableLocalAuthentication="true" />Here is the updated selection form when Local Authentication is included
Related topics: Jazz Authorization Server Landing Page
External links:
Contributions are governed by our Terms of Use. Please read the following disclaimer.
Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.