How to set session attribute in sso app service provider

Hi guys,

Application A is Identity Provider (IDP) http://localhost:8080/app
Application B is Service Provider (SP) http://localhost:8082/app

Both applications have implemented the db-per-tenant approach explained in this example: and discussed here:
After logging in, Application A will display an extended AbstractMainWindow, where an user can choose from an optionsList the database which he wants to work with.
After choosing the database, the user clicks a button and a new tab is opened with the application B. On button click, I used the folowing code to open app B in a new tab.

WindowManager wm = getWindowManager();

This is working good, regarding SSO (it redirects to application B and no login page is displayed)
Also on button click, before opening app B with the code above, I have set the session attribute:


After this, the Session Attribute tenantDbAddress is present in application A but it’s not present in application B so the connection to the additional datastore is not made.
I want to ask you if this is a normal behavior considering that authentication is made from Application A?
If yes, which is the way to send the database parameter from app A to app B and set the session attribute to trigger the connection creation?

Thank you.



It is a really interesting system architecture. Thanks for sharing your experience!

First of all, let me clarify implementation details of IDP:

  • IDP SSO subsystem is developed to be useful not only for CUBA-based web applications. It can be used by any third party application that can use IDP as a simple web service to authenticate users.
  • IDP stores information about authentication using separate objects - IdpSession, it does not use standard UserSession.
  • IdpSession is a record about centralized authentication across applications. It is stored on a middle ware of a server that plays role of IDP.
  • If you use IDP with CUBA-based service provider then IdpSession ID is stored as a session attribute of UserSession object - “idpSessionId”.
  • IdpSession contains its own session attributes that can be updated only from a server with IDP role.

At the moment, there is no convenient API to update IdpSession attributes, but you can do it yourself:

  1. Create middle ware service
  2. Implement method that will obtain IdpSession for currently logged in user and update its attributes:

public class DemoIdpServiceBean implements DemoIdpService {
    private IdpSessionStore idpSessionStore;
    private UserSessionSource userSessionSource;

    public void setTenantToIdpSession(String tenant) {
        UserSession userSession = userSessionSource.getUserSession();
        String idpSessionId = userSession.getAttribute(IdpService.IDP_USER_SESSION_ATTRIBUTE);

        if (idpSessionId != null) {
            IdpSession idpSession = idpSessionStore.getSession(idpSessionId);
            if (idpSession != null) {
                Map<String, Serializable> attributes = idpSession.getAttributes();
                if (attributes == null) {
                    attributes = new HashMap<>();
  1. Execute this method in application with IDP role
  • There is only one drawback with this solution: if you use middle ware cluster for IDP application then it will not update cluster state with for IDP session attributes. This has been fixed in

IdpSession attributes can be loaded in a service provider using the following way:

  1. Obtain IDP session id from UserSession
  2. Perform HTTP Get request to IDP and read IDP session details

public class ExtAppMainWindow extends AppMainWindow {
    private UserSession userSession;
    private WebAuthConfig webAuthConfig;

    public void init(Map<String, Object> params) {

        String idpSessionId = userSession.getAttribute(IdpService.IDP_USER_SESSION_ATTRIBUTE);

        // now we have to use HTTP request to get whole session object from IDP
        // see com.haulmont.idp.controllers.IdpServiceController
        String idpBaseURL = webAuthConfig.getIdpBaseURL();
        if (!idpBaseURL.endsWith("/")) {
            idpBaseURL += "/";
        String idpSessionGetUrl = idpBaseURL + "service/get";

        URI sessionGetUri;
        try {
            sessionGetUri = new URIBuilder(idpSessionGetUrl)
                    .addParameter("idpSessionId", idpSessionId)
                    .addParameter("trustedServicePassword", webAuthConfig.getIdpTrustedServicePassword())
        } catch (URISyntaxException e) {
            throw new RuntimeException("incorrect URL");

        HttpGet httpGet = new HttpGet(sessionGetUri);

        HttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager();
        HttpClient client = HttpClientBuilder.create()

        String idpSessionJson;
        try {
            HttpResponse httpResponse = client.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                // error handling
            idpSessionJson = new BasicResponseHandler()
        } catch (IOException e) {
            // error handling
        } finally {

        // now we can parse idpSessionJson content and read session attributes

I’ve created a small demo of this approach, see

Please note, that it is not a production ready way to work with IDP and you have to test it and adopt to your needs.

We are planning to introduce convenient APIs for such a IDP<->SP interaction in the future after we collect feedback from the community.

Hi Yuriy,

Thanks for the detailed answer.

I tested the demo and i see the attribute set on idpsession on idp app.
If i open the sp app I get the error bellow.

I’ve attached both archives

Thank you

29-Jun-2017 21:21:24.111 SEVERE [http-nio-8082-exec-26] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [app_servlet] in context with path [/app] threw exception
 java.lang.RuntimeException: Unable to invoke no-args constructor for interface Register an InstanceCreator with Gson for this type may fix this problem.
	at com.haulmont.cuba.web.auth.IdpAuthProvider.getIdpSession(
	at com.haulmont.cuba.web.auth.IdpAuthProvider.doFilter(
	at com.haulmont.cuba.web.sys.CubaHttpFilter.filterByAuthProvider(
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(
	at org.apache.catalina.core.StandardWrapperValve.invoke(
	at org.apache.catalina.core.StandardContextValve.invoke(
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(
	at org.apache.catalina.core.StandardHostValve.invoke(
	at org.apache.catalina.valves.ErrorReportValve.invoke(
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(
	at org.apache.catalina.core.StandardEngineValve.invoke(
	at org.apache.catalina.connector.CoyoteAdapter.service(
	at org.apache.coyote.http11.Http11Processor.service(
	at org.apache.coyote.AbstractProcessorLight.process(
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(
	at java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.util.concurrent.ThreadPoolExecutor$
	at org.apache.tomcat.util.threads.TaskThread$
Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name:
	at$14.construct( (25.7K) (20.8K)

Any updates about this issue?



I’ve reproduced the issue. It is caused by our usage of Gson library that can perfectly deserialize Map<String, Object> but fails with Map<String, Serializable>. I’ll fix it for the upcoming 6.6 release, see this issue:

Thank you! It’s ok now.