How to Integrate Existing SSO Authentication Module to Bonita BPM

Single sign-on AuthenticationGenerally speaking, enterprise applications encompass multiple line-of-business (LOB) applications. These LOB applications are primarily accessed via a common authentication gateway module i.e. by implementing or making use of a single sign-on authentication. Is it similar in Bonita BPM application too? Let’s find out, along with this, we will also figure out the process of integrating an existing SSO authentication module to Bonita BPM application.

SSO Authentication

When the Bonita BPM application is added to an existing enterprise application stack, Bonita BPM users are authenticated via an existing SSO authentication module, instead of Bonita BPM application’s login module. After successful authentication by the SSO module, users are directed to the Bonita BPM application’s home page without seeking any additional login credentials.

Customer Authentication Module

Here’s a high-level process to integrate the customer authentication module in Bonita BPM. In the example cited for reference, we have utilized Bonita 6.3.1 and Oracle Access Manager (OAM) for the authentication module. Generally speaking, the Bonita BPM application is accessed via an enterprise dashboard, where authentication is performed against OAM service. The below diagram clearly illustrates the SSO authentication mechanism employed by the Bonita BPM application.

Image depicting SSO Authentication in Bonita BPM

 

Implementing SSO Authentication 

Implementing SSO Authentication in the Bonita BPM application is a fairly simple process. The implementation process has been divided into five simple steps to make the users easily understand the concept of SSO Authentication in Bonita BPM.

  1. Create a standalone Java project with Bonita BPM dependencies.
  2. Implement SSOIntegrationFilter logic to validate the authentication cookie/token as per respective SSO mechanism, which is followed by the custom authentication module.
  3. Implement logic to create APISession for trusted users.
  4. Build a JAR and add to the Bonita BPM classpath.
  5. Define SSOIntegrationFilter configuration into Bonita web.xml.

Step 1 – Creating a standalone Java project with Bonita BPM dependencies

The first step is to create a standalone maven project and define all the required dependencies in the pom.xml file. Below is the code, which would help you achieve this activity:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.company.bonita6</groupId>
 <artifactId>bonita-dashboard-sso</artifactId>
 <version>1.0</version>
 <packaging>jar</packaging>

 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <bonita.version>6.3.1</bonita.version>
 <spring.version>3.1.1.RELEASE</spring.version>
 <spring.security.version>3.1.0.RELEASE</spring.security.version>
 <java.version>1.6</java.version>
 </properties>

 <dependencies>
 <dependency>
 <groupId>com.bonitasoft.engine</groupId>
 <artifactId>bonita-server-sp</artifactId>
 <version>${bonita.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.bonitasoft.console.common.server</groupId>
 <artifactId>common-server-sp</artifactId>
 <version>${bonita.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.bonitasoft.engine</groupId>
 <artifactId>bonita-common-sp</artifactId>
 <version>${bonita.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.bonitasoft.engine</groupId>
 <artifactId>bonita-client-sp</artifactId>
 <version>${bonita.version}</version>
 <scope>provided</scope>
 </dependency>
 </dependencies>
</project>

Step 2 – Servlet Filter Implementation

Subsequently, implement a servlet filter to ensure that each request has a valid SSO cookie/token. Bonita BPM users also need to ensure that the token/cookie has not expired. As mentioned earlier, the process requires invoking the OAM web service to validate a cookie/token. Here’s the servlet filter implementation code:

public class CustomSSOIntegrationFilter implements Filter {
public void doFilter(ServletRequest servletRquest,
 ServletResponse servletResponse, FilterChain chain)
 throws IOException, ServletException {

 HttpServletRequest httpRequest = (HttpServletRequest) servletRquest;
 HttpSession httpSession = httpRequest.getSession();

 /**
 * Create Bonita session, if the user is a trusted user and session not yet
 * available.
 */
 if (httpSession.getAttribute(BONITA_SESSION) == null) {

 String ssoCookie = retrieveSSOCookie(httpRequest);

 if (ssoCookie == null || ssoCookie.trim().length() == 0) {
 /**
 * This is to ensure that if Bonita portal is accessed
 * directly (in case of Admin, Install, etc.) user will be
 * redirected to login page and SSO is ignored.
 */
 if (LOGGER.isLoggable(Level.WARNING)) {
 LOGGER.log(
 Level.WARNING,
 " ssoCookie is not available in the request, the user will be redirected to Bonita login page.");
 }

 } else {
 if (LOGGER.isLoggable(Level.FINE)) {
 LOGGER.log(Level.FINE, "Found ssoCookie in Request....."
 + ssoCookie);
 }
 String trustedUser = new OAMServiceStub(OAM_SERVICE_URL).authenticateSSOCookie(ssoCookie);

 if (trustedUser == null || trustedUser.trim().length() == 0) {
 new InvalidUserException(
 "Invalid User credentials. Please login with valid user credentials.");
 }

 BonitaSessionCreator.getInstance().createSession(httpRequest,
 trustedUser);
 }
 }

 chain.doFilter(httpRequest, servletResponse);

 }
private String retrieveSSOCookie(final HttpServletRequest request) {
 String ssoCookie = "";
 Cookie cookies[] = request.getCookies();
 if (cookies != null) {
 for (int i = 0; i < cookies.length; i++) {
 if (cookies[i].getName().equalsIgnoreCase(SSO_COOKIE)) {
 ssoCookie = cookies[i].getValue();

 }
 }

 }
 return ssoCookie;
 }
}

Step 3 – Create APISession

Once the SSO authentication module successfully validates a cookie/token, the next step is to create an APISession using Bonita BPM application’s login API. Please make a note, when an APISession is available in the request, Bonita BPM does not redirect users to the login page till the user session is valid.

public class BonitaSessionCreator {

 private static final Logger LOGGER = Logger
 .getLogger(BonitaSessionCreator.class.getName());

 private static final String BONITA_SESSION = "apiSession";

 private static BonitaSessionCreator sessionCreator = null;

 public synchronized static BonitaSessionCreator getInstance() {
 if (sessionCreator == null) {
 sessionCreator = new BonitaSessionCreator();
 }
 return sessionCreator;
 }

 public void createSession(HttpServletRequest httpRequest, String trustedUser)
 throws ServletException {
 HttpSession httpSession = httpRequest.getSession();
 /**
 * trusted user name is considered as default password to log onto
 * bonita. Or we can obtain the password form SSO module too.
 */
 String password = trustedUser.toLowerCase();
 try {
 loginIntoBonita(trustedUser, password, httpSession);
 } catch (LoginException le) {
 if (LOGGER.isLoggable(Level.WARNING)) {
 LOGGER.log(Level.WARNING,
 "Unable to login into Bonita for trusted user = "
 + trustedUser);
 }
throw new ServletException(e);

 }
 }

 private APISession loginIntoBonita(String trustedUser, String password,
 HttpSession httpSession) throws ServletException, LoginException {
 APISession apiSession = null;
 try {
 LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
 apiSession = loginAPI.login(trustedUser, password);
 httpSession.setAttribute(BONITA_SESSION, apiSession);
 if (LOGGER.isLoggable(Level.FINE)) {
 LOGGER.log(Level.FINE, "Bonita session created for the user= "
 + trustedUser);
 }
 } catch (LoginException le) {
 throw le;
 } catch (Exception e) {
 if (LOGGER.isLoggable(Level.SEVERE)) {
 LOGGER.log(
 Level.SEVERE,
 "Error while creating bonita session for the user = "
 + trustedUser + ", " + password
 + e.getMessage(), e);
 }
 throw new ServletException(
 "Unable login into Bonita Portal. Please contact System Administrator. "
 + e.getMessage());
 }
 return apiSession;
 }

 }

Step 4 – Building the Bonita Java Project

This is an important step, execute the maven install/build command to build a standalone Bonita Java project .jar file. Here’s the code snippet, which would help you accomplish this activity:

<Bonita_Home>/webapps/bonita6/WEB-INF/lib/bonita-custom-sso-1.0.jar

Step 5 – SSOIntegrationFilter Configuration into Bonita web.xml

The final step is to add SSOIntegrationFilter configuration in the Bonita web.xml file. Add the below filter mapping element in the web.xml file, which can be located in the path mentioned below.

</pre>
<h6><span style="color: #000000;">Add the below filter definition before “InternalSSOFilter” filter definition</span></h6>
<pre>
 <!-- Custom SSO filter definition-->
<filter>
 <filter-name>CustomSSOIntegrationFilter</filter-name>
 <filter-class>com.company.bonita6.sso.filter.CustomSSOIntegrationFilter</filter-class>
</filter>
Add the below filter mapping before “AuthenticationFilter” filter mapping:
<!-- Custom SSO filter mapping-->
 <filter-mapping>
 <filter-name>CustomSSOIntegrationFilter</filter-name>
 <url-pattern>/portal/BonitaConsole.html</url-pattern>
 </filter-mapping>
 <filter-mapping>
 <filter-name>CustomSSOIntegrationFilter</filter-name>
 <url-pattern>/portal/homepage</url-pattern>
 </filter-mapping>
Add the below filter mapping before “ShutdownListener” listener:
<filter-mapping>
 <filter-name>AuthorizationFilter</filter-name>
 <url-pattern>/portal/BonitaConsole.html</url-pattern>
 </filter-mapping>
 <filter-mapping>
 <filter-name>AuthorizationFilter</filter-name>
 <url-pattern>/portal/homepage</url-pattern>
</filter-mapping>

Conclusion

The above guidance would certainly help Bonita BPM users to integrate existing SSO Authentication module to Bonita BPM application. Although, users are authenticated via the SSO authentication module, Bonita BPM application still requires user data to be present in the Bonita user tables in journal schema. The Bonita BPM application performs workflow/task authorization based on a users membership level. Nevertheless, there are several other ways to sync users information from LDAP/AD into Bonita Journal, which is an altogether different topic and can be discussed in a separate blog.

Hari Prasad Alla

View posts by Hari Prasad Alla
Hari Prasad Alla is a Associate Technical Architect at Evoke Technologies. He has strong expertise in requirements analysis, design, implementation and release. He has technically adept in Bonitasoft BPM, Java, Spring MVC, Spring Batch, Spring Integration, Hibernate, Web Services (SOAP, REST), JMS, Jasper reports, Hadoop and NoSQL (MongoDB).

11 Comments

    1. Hi Alex,

      SSO cookie is not distinct than a regular http cookie. The value of the cookie depends on authentication service that is being used. In this case, we set encrypted token that is generated by an OAM server. Hence, we request OAM service to validate the token for the next consecutive user requests.

      Please let us know if you are looking for any other specific information.

      Thanks,

      Hari Alla

      1. Hi,

        I added necessary cookies, but there is another problem, it seems that i must set also PERMISSIONS_SESSION_PARAM_KEY (“permissions”) session attribute, otherwise i’m getting error: Permission denied: you do not have the rights to perform this action.

        Thanx, Alex.

        1. Thanks Alex for the update, we implemented this using 6.5 version. I am not too sure if PERMISSIONS_SESSION_PARAM_KEY is newly added in 7.0 version. Could you please let me know when do you get the error? And are you able to see Bonita portal page? Does the user has ‘User’ profile configured?

          1. I had to use bonita private PermissionsBuilderAccessor class (added console-common-7.3.2.jar dependency to maven), could not find any other way:


            LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
            apiSession = loginAPI.login(trustedUser, password);
            long userId = apiSession.getUserId();
            IdentityAPI identityAPI = TenantAPIAccessor.getIdentityAPI(apiSession);
            User user = identityAPI.getUser(userId);

            PermissionsBuilder permissionBuilder = PermissionsBuilderAccessor.createPermissionBuilder(apiSession);

            Set permissions = permissionBuilder.getPermissions();

            httpSession.setAttribute(API_SESSION_PARAM_KEY, apiSession);
            httpSession.setAttribute(USERNAME_SESSION_PARAM, apiSession.getUserName());
            httpSession.setAttribute(USER_SESSION_PARAM_KEY, user);
            httpSession.setAttribute(PERMISSIONS_SESSION_PARAM_KEY, permissions);

  1. Hi Hari,

    I’m working on Bonita 7.2. I have a requirement of configuring SSO with CAS in Bonita. I have implemented it using Bonita document but I need to do some customization here. After CAS login page before redirecting to home page some custom code needs to be added. Can you help me in understanding how custom CAS filter can be implemented.

    Thanks,
    Amit

    1. Hello Amit,

      Firstly, apologies for the delay in responding to your comments.

      After successful authentication, Bonita BPM redirects the page to source URL (custom app). You may add a servlet filter in the Bonita web.xml file for your source URL. If you are accessing the general Bonita BPM portal, it redirects you to the /portal/homepage, which enables you to add filter mapping to the homepage URL.

      Regards,

      Hari Alla

      1. Hello Hari,

        Thank you for the reply.
        Could you please explain this with steps like you have mentioned for SSO Authentication above.

        Regards,
        Amit

    1. Thanks Jose for the feedback.

      We haven’t tested this in Community version. However, we believe this approach should work in community platform. Please let us know if we can help you.

      Hari

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

%d bloggers like this: