Single Sign On Integration with Portofino - JOSSO
Posted by Giampiero Granatella
on March 30, 2009
In this tutorial I'll explain how to change the authentication and authorization mechanism of ManyDesigns Portofino. We'll integrate Portofino with a popular Single Sign On (SSO) product: JOSSO (Java Open Single Sign-On). The advantage of using a SSO is that users can use a single login/password to access a multitude of web applications and systems.
JOSSO is a Spring-based SSO infrastructure that provides centralized, platform-neutral authentication and authorization. It is open source (LGPL), written in Java, and runs on most application servers (JBoss, Tomcat, Jetty, WebLogic ...). It can be also accessed by other applications written in ASP, php, etc, or via web services.
You would change the authentication of Portofino in these scenarios:
- Your Portofino app belongs to a set of web applications that share the same base of users. You want your users to be able to log in once and gain access to all the applications.
- Your users are stored in an external system, e.g. an LDAP server, a legacy database, a MS Windows Domain, ecc...
- You want to manage encrypted passwords in Portofino.
- You want a separate system for Identity Management.
- You want a complete solution for password recovery (via email) and reset.
JOSSO 1.8 has a quick start guide at http://www.josso.org/confluence/display/JOSSO1/Quick+Start, which refers to Tomcat 6. In this section, I'll summarize those installation instructions briefly.
Installing JOSSO is very simple. It has an interactive shell called Deployment Console (bin/josso-gsh.sh in JOSSO's installation dir) from which you can install the two components of JOSSO:
- SSO Gateway (IdP): The SSO server, also known as Identity Provider, responsible of acting as the web access management authority for SSO-enabled applications and their users.
- SSO Agent (SP): Handles the single sign-on use-cases and execution environment integration details for SSO-enabled applications. The agent consumes Gateway identity services.
Use the following commands to install the Gateway and the Agent. You have to specify the path to your aplication server, and the platform (e.g. tc60 correspond to tomcat 6).
josso> gateway install --target path_to_tomcat/apache-tomcat-6.0.18 --platform tc60
josso> agent install --target path_to_tomcat/apache-tomcat-6.0.18 --platform tc60
That's all. The previous commands configure your Tomcat installation to run JOSSO. Physically they copy various configuration files, jars and the wars (JOSSO server and a demo client) to your server.
To install JOSSO on platforms other than Tomcat, see section "2.2.2 Gateway Install Matrix" at http://www.josso.org/confluence/display/JOSSO1/Setup+JOSSO+Gateway+(IdP).
If you haven't installed Portofino yet, make sure you read "Portofino tutorial part 1: Installing and running the software".
JOSSO has many XML configuration files to customize its behavior. They are located in your application server's classpath, e.g. in Tomcat 6 they are in the 'lib' folder. The main files are the following:
- josso-gateway-config.xml - The main configuration file for the gateway, in which all the submodules are linked.
- josso-agent-config.xml - The main configuration file for the agent; this file lists the partner applications that use JOSSO for authentication.
- josso-gateway-stores.xml - this tells JOSSO how to obtain user's identity information like username, roles, credentials, etc. It defines the specific persistence mechanism used to retrieve the data
- josso-credentials.xml - a collection of username and password, used if you choose to store users on the file system
- josso-gateway-db-stores.xml - DB connection properties, used if you choose to store users on a DBMS
- josso-gateway-ldap-stores.xml - LDAP connection properties, used if you choose to store users on a LDAP server
- josso-users.xml - user metadata and roles, used only if you choose to store user on the file system
In this tutorial, we'll customize only files 2 and 7. You can leave the others to their default, or customize them later.
For simplicity we will authenticate with users stored on the filesystem (later you can switch to LDAP or a DB, see http://www.josso.org/confluence/display/JOSSO1/Database+Setup).
Edit the josso-users.xml file. Add the "Users" role and associate "user2" (or any othe built-in user) to it. The changes are shown in bold:
... <user> <name>user2</name> <!-- Optionally, define some properties for this user --> <properties> <property> <name>user.name</name> <value>User 2 Name</value> </property> <property> <name>user.lastName</name> <value>User 2 Last Name</value> </property> <property> <name>user.registrationDate</name> <value>2004/09/10</value> </property> <property> <name>email</name> <value>email@example.com</value> </property> </properties> <!-- Optional comma sepparated set of roles, must be defined below --> <roles>role2, Users</roles> </user> ... <!-- Roles definitions --> <roles> <role> <name>role1</name> </role> <role> <name>role2</name> </role> <role> <name>Users</name> </role> </roles> </josso-users>
Tell JOSSO that your Portofino instance is a partner application by adding the following lines to the filejosso-agent-config.xml
<agent:partner-apps> <agent:partner-app id="Portofino" context="/portofino"/> </agent:partner-apps>
Here we are assuming that Portofino is running under the /portofino context.
First configure Portofino to use the container-managed security (see Single sign-on) by adding the following line to portofino-custom.properties
Any Java EE application that needs container-managed security has to configure a "security-constraint" section in the web.xml file.
Edit Portofino's WEB-INF/web.xml. It already has a commented security-constraint section. Uncomment it and modify it as follows (changes shown in bold).
<security-constraint> <web-resource-collection> <web-resource-name>Servlets</web-resource-name> <description>Servlets under container-managed security</description> <url-pattern>/upstairs/AddVersion</url-pattern> <url-pattern>/ChangePassword</url-pattern> ... <http-method>GET</http-method> <http-method>POST</http-method> <http-method>HEAD</http-method> <http-method>PUT</http-method> <http-method>OPTIONS</http-method> <http-method>TRACE</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint> <description> User Group </description> <role-name>Users</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login-redirect.jsp</form-login-page> <form-error-page>/login-redirect.jsp</form-error-page> </form-login-config> </login-config> <security-role> <description> Users Group </description> <role-name>Users</role-name> </security-role>
Notice that the role name "Users" must match the role name defined in josso-users.xml.
Also (see section "login-config"), we added two jsp files for the authentication and error pages.
A few more changes to the web.xml. Now we need to modify one of the servlets. Locate the 'Login' servlet - it looks like this:
<servlet> <servlet-name>Login</servlet-name> <servlet-class>com.manydesigns.portofino.methods.Login </servlet-class> </servlet>
Change it to this:
<servlet> <servlet-name>Login</servlet-name> <jsp-file>/logout-redirect.jsp</jsp-file> </servlet>
Create two files called login-redirect.jsp and logout-redirect.jsp under the root of your Portofino instance, and add the following content. These two pages redirect login and logout to the corresponding JOSSO actions.
<%@page contentType="text/html; charset=UTF-8" language="java" session="true" %> <% response.sendRedirect(request.getContextPath() + "/josso_login/"); %>
<%@page contentType="text/html; charset=UTF-8" language="java" session="true" %> <% response.sendRedirect(request.getContextPath() + "/josso_logout/"); %>
Start your Tomcat and go to http://localhost:8080/portofino, you'll be redirected to the JOSSO login page.
Use a JOSSO demo users (e.g. user1/user1pwd) and log in. The system will return you to Portofino and you should see that you are logged in as user1.
Portofino automatically adds any users authenticated through JOSSO to its internal database. This is handy if you want to reference user objects in your applications (e.g. as path actors).
Now that you have JOSSO and Portofino up and running together, you can enable other JOSSO features with little additional effort:
Change the way the login page looks
Use digital certificates (Strong authentication)
Set up Windows Authentication
Customize the password reset process