Security Global Forum

 View Only

Getting Started with IBM Single Sign On for Bluemix

By Shane Weeden posted Wed March 11, 2015 12:00 AM

  

This article will focus on helping you get started with using the IBM Single Sign On Service for Bluemix.

What is IBM Bluemix?

Put simply, IBM Bluemix is a Platform-as-a-Service (PaaS) offering from IBM. Based on CloudFoundry open source technology, IBM Bluemix allows developers to rapidly assemble and deploy applications. What differentiates IBM’s PaaS offering is the wealth of value-add services from both IBM’s middleware stack and partners.

What is IBM Single Sign On for Bluemix?

The single sign on service for Bluemix allows a developer to add authentication services to their application in less than an hour.

Actually, much less in most cases. How could that be?

The single sign on service does this by providing zero-code (or minimum-code) integration of single sign on into applications. A security administrator creates a service instance, then configures one or more “identity sources” for that service instance. A developer then binds that service instance to their application. Specifically for J2EE applications that use the Liberty Java application runtime on Bluemix, the act of binding the service instance to the application results in completely automated configuration of federated single sign on security between the original identity sources and the target application.

Let’s look at these components in more detail:

The left side of the diagram represents one or more identity sources configured for an instance of the Single Sign On service. The right hand side represents consuming applications. For the purposes of this introduction, we will discuss the configuration of the In-Cloud Directory (since it requires no configuration of any external entity) alongside a Java web application written to run on the Liberty runtime on Bluemix.

Creating and Configuring a Single Sign On service instance

A pre-requisite to this activity is that you have a Bluemix account, either a 30-day trial, or a full registered account. At the time of writing this article, the Single Sign On service is only available in the US region for Bluemix, so the console you need to be able to login to is located at:

https://console.ng.bluemix.net

In the organization and space of your choice, create a new instance of the IBM Single Sign on for Bluemix Service. The logo for the service looks like this:

When creating the instance, be sure to assign it a short name, and Leave Unbound. This is important as the service may not be bound to an application until such time as it is correctly configured:

After the service instance is created, you will be prompted to provide a short service name which will become part of the URL hostname for your specific service instance. You should enter a meaningful, simple short name from URL-safe characters and press continue:

The next step is to configure one or more Identity Sources. In this example we will configure just the Cloud Directory identity source, and add a testuser to it. Select Cloud Directory, then add a testuser with basic properties, as shown:

Save the user, then press Save again for the cloud directory panel itself:

Congratulations, your Single Sign On service instance is now configured and ready to use with an application.

Writing a J2EE Application with Declaritive Security

In this section we will prepare a HelloWorld style application which requires authentication to access the main index page of the app and displays the authenticated username. Later we will deploy this application to Bluemix and have it work with the configured Single Sign On service.

First let me say that the entire EAR application that will be discussed in this section, with source, is available for download here.

To write this application I have used standard Eclipse (Luna). I added on the IBM Bluemix Eclipse Plug-in, and built EAR (Enterprise Application) and WAR (Dynamic Web Project) projects. The WAR project has two important files – the main index.jsp page, and the web.xml deployment descriptor. First let’s take a look at the index.jsp page:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    session="true"
    import="java.util.Set"
    import="java.security.Principal"
    import="javax.security.auth.Subject"
    import="com.ibm.websphere.security.auth.WSSubject"
%>
<%
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Cache-control", "no-store");
        
    Subject s = WSSubject.getCallerSubject();
    String username="unknown";
    if (s != null) {
        Set<Principal> principals = s.getPrincipals();
        if (principals != null && principals.size() > 0) {
            // in production this should be html encoded for safety
            username = principals.iterator().next().getName();
        }
    }
%>
<html>
Hello: <%=username%>
<br />
Click <a href="dumpSubject.jsp">here</a> for a more elaborate 
breakdown of the JAAS Subject.
</html>

As you can see from this very simple JSP, the username is extracted from the first available Principal in the JAAS Subject, which is retrieved using the WSSubject class from WebSphere.

Now let’s take a look at web.xml which defines security contraints and required roles for application resources. This file basically says that access to index.jsp requires the user to be authenticated with the “any-authenticated” role.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
        <display-name>BMSSODemoWAR</display-name>
        <welcome-file-list>
                <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    <security-constraint>
                <web-resource-collection>
                        <web-resource-name>bmssodemo</web-resource-name>
                        <url-pattern>/*</url-pattern>
                </web-resource-collection>
                <auth-constraint>
                        <role-name>any-authenticated</role-name></auth-constraint>
        </security-constraint>
</web-app>

The EAR project also contains two important files in the META-INF directory. These are the application.xml which references the WAR project and sets the context root, and the ibm-application-bnd.xml which maps roles defined in the web.xml to subjects (such as users or groups). In our case we will map the any-authenticated role to a special subject defined by Liberty called ALL_AUTHENTICATED_USERS.

For more information on role mapping please see http://www-01.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/cwlp_authorization.html

Here is the content of the ibm-application-bnd.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<application-bnd
        xmlns="http://websphere.ibm.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-bnd_1_2.xsd"
        version="1.2">

        <security-role name="any-authenticated">
                <special-subject type="ALL_AUTHENTICATED_USERS" />
        </security-role>
</application-bnd>

The application.xml just maps the context root of the war file to the root of the application, meaning we can deploy this app and access the top-level URL to reference the index page.

Here is the content of the application.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<application id="Application_ID" version="6" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd">
 <display-name>BMSSODemoEAR</display-name>
 <module id="Module_1426050503022">
        <web>
                <web-uri>BMSSODemoWAR.war</web-uri>
                <context-root>/</context-root>
        </web>
 </module> 
 </application> 

Remember, the entire EAR application, with source, is available for download here.

Deploy your application to Bluemix

There are many ways to deploy your application to Bluemix – you can use a plug-in to eclipse to push the application directly to Bluemix from the eclipse GUI, however personally I choose to export the EAR from Eclipse to a file, then use the cf command line tool to push the application manually. There are plenty of examples you can Google to figure out how to do this. I don’t plan to cover application deployment tools in this article.

Ultimately you should have the application running on Bluemix, although without authentication working. Accessing the application root with a browser will show “unknown” as the username because we don’t yet have authentication working for the app.

Bind the Single Sign On service to your application

Log back into the Bluemix console at https://console.ng.bluemix.net and navigate to your new application. Click “Bind a service or API”, select the Single Sign On service we configured earlier, then when prompted, restage the application.

Wait until the application restages – you will see progress information in the Bluemix console.

You have now added authentication to your Java Liberty application on Bluemix, and it is ready to test.

Test your application

Now, when you reaccess your application you should be taken through an authentication sequence where you can login using the In-Cloud Directory that was configured for the service:

Advanced user information

You will see that the application contains a link to a more advanced page called dumpSubject.jsp which uses WebSphere API’s to decompose and print out in text format all the available credential information from the JAAS Subject. I’ll leave it as an exercise for you to go look at the jsp and helper classes I have provided with the application if you wish to know how that is done.

Of particular interest to some will be the decomposition of the id_token that is part of the OpenID Connect single sign on that occurs between the Single Sign On service and the Java applicaiton. Here is an example screenshot of that from my deployment of the demo app:

There are actually many claims, reformatted they look like this:

{
    "exp": 1426060489,
    "realmName": "mga",
    "sub": "testuser",
    "at_hash": "OIiaApMSDe0vBSCPs83pfA",
    "uniqueSecurityName": "testuser",
    "aud": "8q2cZ4B07C",
    "iss": "blogdemo-n5vby4fjim-crp3.iam.ibmcloud.com",
    "emailAddress": "testuser@test.com",
    "iat": 1426060189,
    "ext": "{}"
}

The Wrap

I hope you can see from this article that once you have enabled yourself on working with Bluemix, and developing J2EE applications, the actual exercise of using the Single Sign On service to add authentication to your application is actually the most straight forward part of the entire exercise!

In a future article I hope to elaborate on some more of the features of the Single Sign On service such as:

  • Configuring Social identity sources
  • Configuring the SAML Enterprise identity source
  • Customizing the page templates used for a Single Sign On service instance, and why you might want to do that
  • Writing applications for runtimes other than Liberty Java
  • Effective development – how to develop your application locally in Eclipse whilst still using your Bluemix-hosted Single Sign On service instance (YES you can do this!)

Till next time – happy developing.

0 comments
3 views

Permalink