In WSO2 Identity Server, when there are many tenants created; there can be users who may use multiple user accounts to login to the Identity Server where those user accounts are created in different tenants. In such situations, the user needs to remember all the tenant domain names in order to login. With the Service Pack 1, Identity Server 5.0.0 delivers a feature to to display all the active tenant domains in a dropdown in the SSO login page.
In this post I’m demonstrating how to enable this feature in a Single Node Identity Server setup. If it is a clustered setup, some configuration changes are needed and it will be discussed in a future post.
We need to setup the travelocity sample app for this demonstration which is explained in .
After successfully setting up travelocity sample and successfully login to the app through the Identity Server, follow the steps below.
Login to the management console and create a tenant. Here I give the tenant domain as abc.com. The username of the users in this tenant will be <username>@abc.com.
Similarly, create a couple of more tenants.
Now login to the travelocity.com sample with SAML2 authentication.
Here as the username, I am giving ‘email@example.com’ which is the tenant admin account created at the abc.com tenant creation.
When trying to login, it gives me the following error message.
“Service Provider tenant domian must be equal to user tenant domain for non-SaaS applications”
This is because the travelocity.com Service Provider is created in Super Tenant and not under the abc.com tenant.
When a user from a tenant (other than Super Tenant) tries to login to a Service Provider, the Service Provider should be registered under the user’s tenant domain unless the Service Provider is a SaaS application.
If the Service Provider created in Identity Server resides in a tenant (other than Super Tenant), the relying party should send the tenantDomain as a query parameter to the Identity Server.
In travelocity.com sample in the travelocity.properties file, following property can be used for this purpose.
When the tenantDomain query parameter is not received by the Identity Server, the authentication framework in Identity Server assumes that the Service Provider is created inside the Super Tenant.
Instead of creating another Service Provider in the abc.com tenant, I’ll set the travelocity.com Service Provider created in the Super Tenant as a SaaS Application so that users across different tenants can login to the travelocity.com Service Provider.
Now I can login to the travelocity.com sample app with the abc.com tenant admin’s credentials.
Now let’s see how to enable the Tenant Domains dropdown in the login page so that the uses don’t need to type the tenant domain at the end of the username followed by the ‘@’ sign.
Shutdown the Identity Server.
Edit the <IS_HOME>/repository/conf/tomcat/catalina-server.xml file and set the clientAuth property value to “want”.
This is because in this feature, it is using Mutual (2-Way) Authentication  for calling the TenantMgtAdminService of the Identity Server for obtaining the active tenant domains list. The reason for using Mutual Authentication  is because at the time the admin service is called, the user is not logged into the Identity Server and through Mutual SSL Authenticator, Identity Server can allow accessing it’s admin services in a password-less manner. More information can be found in .
The clientAuth="want" tells Tomcat to request that the Browser provide a User certificate if one is available.
Then, copy the mutual-ssl-authenticator jar file to the <IS_HOME>/repository/components/dropins directory. This jar file can be found inside the following path in the Identity Server Service Pack 1.
In order to enable the Mutual SSL Authenticator, add the following configuration to the <IS_HOME>/repository/conf/security/authenticators.xml file under the <Authenticators> tag.
<!-- Authenticator Configurations for MutualSSLAuthenticator-->
<Authenticator name="MutualSSLAuthenticator" disabled="false">
If the SAML2SSOAuthenticator is already enabled (disabled="false") in <IS_HOME>/repository/conf/security/authenticators.xml file in your setup, set it's priority to 0.
Otherwise ignore this step.
<Authenticator name="SAML2SSOAuthenticator" disabled="false">
This is for properly engaging the MutualSSLAuthenticator which should having a higher priority.
Add following configuration to the <IS_HOME>/repository/conf/security/application-authentication.xml file under the <ApplicationAuthentication> tag. This configuration is needed for the authentication framework to notify the authentication endpoint webapp upon any change made to a tenant such as adding new tenant, deactivate a tenant and activate a tenant so that it can update the active tenant domains list inside the authentication endpoint webapp where the login page is contained.
Making TenantDomainDropDownEnabled property value to true enables the listener which listens to the changes to Tenants and upon such a change, it notifies the authenticationendpoint webapp. The URL to the authenticationendpoint’s tenantlistrefresher.do servlet should be given in TenantDataListenerURL property. If the authenticationendpoint webapp is hosted in a separate server (other than the embedded tomcat in Identity Server), fully qualified URL should be given (i.e : http://<hostname>:<port>/authenticationendpoint/tenantlistrefresher.do)
The login page where the dropdown is included is contained in the authenticationendpoint web app which is by default deployed in the inbuilt tomcat in Identity Server (<IS_HOME>/repository/deployment/server/webapps/authenticationendpoint.war). This webapp can be deployed in a separate Tomcat server or in a WSO2 Application Server instance. In this feature, It calls the TenantMgtAdminService through Mutual Authentication for obtaining the list of active tenant domains. For Mutual Authentication, the authenticationendpoint webapp needs to have a keystore and a truststore where the public certificate of the Identity Server should be imported to the truststore of the webapp and the public certificate of the webapp should be imported to the truststore of the Identity Server.
The authenticationendpoint webapp contains the following property file which contains the properties required for Mutual Authentication.
Following are the default values for the properties.
- tenantListEnabled property controls whether this feature is enabled or not. If enabled and when a relying party application visits the login page, if the tenant domains list is not available inside the authenticationendpoint webapp, it calls the TenantMgtAdminService and retrieves the active tenant domains list through Mutual Authentication.
- For Mutual Authentication, a username of a valid user in Identity Server should be given for mutual.ssl.username. This user should possess the following permission in order to retrieve the active tenants list. Here I have given the admin username as it contains all the permissions by default. (At the end of this post, a security recommendation is given regarding the correct usage of the username)
Super Admin Permissions > Manage > Monitor > Tenants > List
- The keystore path and the keystore password of the authenticationendpoint webapp are given in client.keyStore and client.keyStore.password properties respectively. Here since the authenticationendpoint webapp is hosted in the embedded tomcat server in Identity Server, the same keystore of the Identity Server is used which is given as a relative path. If a separate keystore is used for this feature, the particular path and the password should be specified.
- Similar to the keystore above, the truststore path and password are given in client.trustStore and client.trustStore.password properties.
- The hostname of the Identity Server and the running port should be specified in identity.server.host and identity.server.port properties. This is useful when the authenticationendpoint webapp is hosted in a separate server and the Identity Server is running in a separate server. Since the authenticationednpoint webapp running inside the Identity Server here, localhost is used as the hostname.
- The username specified in mutual.ssl.username which is used for Mutual Authentication should be sent to the Mutual SSL Authenticator in Identity Server when calling the TenantMgtAdminService. In the request SOAP message, this username should be included in the SOAP header. The header name where the Mutual SSL Authenticator accepts the username is given in username.header. By default the value for this is ‘UserName’. This value should be matched with the UserNameHeader property value given in the MutualSSLAuthenticator configuration in <IS_HOME>/repository/conf/security/authenticators.xml file.
Next step is to import the public certificates in the truststores correctly. Here, since both the Identity Server and the authenticationendpoint webapp are using the same keystore and truststore, it is sufficient to export the public certificate from the keystore and import it to the truststore.
Execute following commands from the <IS_HOME>/repository/resources/security directory.
keytool -export -alias wso2carbon -file identity_server_public.crt -keystore wso2carbon.jks -storepass wso2carbon
keytool -import -trustcacerts -alias identity_server_public -file identity_server_public.crt -keystore client-truststore.jks -storepass wso2carbon
If a separate keystore and a truststore is used by the authenticationendpoint webapp for Mutual Authenticaiton, the public certificate of the Identity Server should be exported from it’s keystore and imported to the truststore of the authenticationendpoint webapp. The public certificate of the authenticationendpoint webapp should be exported from its keystore and should be imported to the truststore of the Identity Server.
Now restart the Identity Server and login to travelocity webapp with SAML2.
Now in the login page, the Tenant Domains Dropdown which lists the active tenant domains should be visible.
Here I select the abc.com tenant from the dropdown.
Now as the username I don’t need to enter the full username as previously. I can enter the username excluding the tenant domain.
Now I have successfully logged into the travelocity app.
Security Recommendation for the Mutual Authentication Username:
In this demonstration I used the ‘admin’ username for the Mutual Authentication. In Security context, we must always define the minimal set of required permissions for users. For this feature, the only required permission is Super Admin Permissions > Manage > Monitor > Tenants > List permission. Therefore we can create a new role assigning this permission and create a new user with this role. In the authenticaitonendpoint webapp, in the TenantConfig.properties file, we can specify this username for the mutual.ssl.username property.
First create a role.
Here we can create an Internal Role because this role is used for Mutual Authentication which happens internally.
Give the permission for listing tenant domains as the only permission for the role.
Create a new user.
Assign the created role to the user.
Specify this username for Mutual Authenticaiton in <IS_HOME>/repository/deployment/server/webapps/authenticationendpoint/WEB-INF/classes/TenantConfig.properties file.
The official documentation for this feature is available in  and the related public JIRA for this feature is in .
How to Disable this feature after enabling :
Modify the <IS_HOME>/repository/conf/tomcat/catalina-server.xml file and set the clientAuth property value to “false”.
In the <IS_HOME>/repository/conf/security/authenticators.xml file under the <Authenticators> tag, find the MutualSSLAuthenticator configuration and set the disabled attribute to “true”.
<!-- Authenticator Configurations for MutualSSLAuthenticator-->
<Authenticator name="MutualSSLAuthenticator" disabled="true">
In <IS_HOME>/repository/conf/security/application-authentication.xml file under the <ApplicationAuthentication> tag, find the <TenantDomainDropDownEnabled> tag and set the value to false.
In <IS_HOME>/repository/deployment/server/webapps/authenticationendpoint/WEB-INF/classes/TenantConfig.properties file, set the tenantListEnabled property value to false.
Identity Server Team