Adding Session Management and Role Validation to SMODL Service
Overview
This tutorial is the second part of the series of articles explaining basics of SMODL service development in Eclipse IDE.
In this tutorial we will expand the service created in here in order to build an account management system with proper session management and authorization based on roles. Test service implementation is available online.
Prerequisites
It is assumed that the reader completed this tutorial and has the project structure in place.
You will need the following software to build the project:
Eclipse IDE for Java EE Developers package. The download package and installation instructions can be found on Eclipse web site. Screenshots in this document are from Eclipse JEE "Galileo" edition.
Tomcat 6.0, available from Apache Tomcat web site. This tutorial was written using version 6.0.18.
JRE 6.0, available from Sun.
Smodl Development Suite at least version 1.3, please visit this page for installation instructions. Screenshots in this tutorial may be from slightly different versions of Smodl Development Suite but should all be relevant for the latest version. If this is not the case, please contact us and let us know!
Step-By-Step Development Process
The service we develop in this tutorial manages accounts. Users register accounts, providing a user name and a password which can be used later to view and modify information related to their accounts.
Authentication (i.e. making sure you are who you claim you are) is handled by logging in with username and password, and subsequently by a session marked by a cookie. The user fills in user name and password in the login form on the site and clicks on "login" button, causing this information to be sent to the server.
The server validates the provided credentials and if it fails the user is asked to try again. If credentials are validated, authentication is successful and the server establishes a session and marks it with a cookie. The browser stores the cookie and applies it to subsequent requests to the server, implementing session-based authentication.
Authorization (i.e. controlling who is allowed to do what) is implemented by role validation as described in the Service Deployment tutorial.
The actual implementation of this can be found further down in this tutorial. The test service implementation is available on our server.
We shall now update the SMODL file named "service.smodl" which is located in "org.smodl.tutorial.service" package. We will add methods to build a simple account management system with login and logout functionality:
Add the code shown below into the SMODL file.
Generation of the Java-Interface for the Service
If the interface was not generated for you automatically, we now activate its generation on the property page of the SMODL file:
Please refer to the SMODL service tutorial part 1, for full interface name.
At this point your service implementation shall be marked as one that has errors. This is expected because we added few methods to the interface it implements.
Addition of Service Method Stubs
Copy the code from listing below into your "org.smodl.tutorial.service.RepositoryServiceImpl" class. This will clear the error.
Now let us consider how to secure method invocation.
Web-service oriented development is originated from the need to create distributed, Internet-based, platform-independent business applications. Organizations wish to collaborate with each other, engage in business transactions with partners all over the world without disclosing confidential information. Which means that business requirements also create access control requirements. Rather than assigning privileges to individual users or operations it is logical to organize users in groups and assign roles to each group. In turn permissions to perform Web-service operations shall be granted to certain roles.
When it comes to the service we create, it worth to mark out three groups of users:
Anonymous users can call method "createNewUser" in order to sign up for the service and to become registered customers. Registered customers can call the rest of service methods in order to maintain their profile information. Advanced users could, for example, restore deleted profiles and/or delete existing users. But implementation of such tasks is behind the scope of this tutorial.
Role Validation in SMODL Service (optional)
The latest implementation of the SMODL runtime allows to control invocation of SMODL service methods using role-based access control described above. If the choice to apply role validation is made, the runtime shall get an object implementing the "IRoleValidator" interface, let's call it "securityService":
private SessionSecurityService securityService = null; securityService = new SessionSecurityService(); runtime.setRoleValidator(securityService);
... and each service method shall get a list of associated roles.
runtime.setRoleMethodMapping(new String[] {
"loginUser","createNewUser"
}, new String[] { "anonymous", "user" });
runtime.setRoleMethodMapping(new String[] {
"logoffUser", "updateProfile",
"getProfile", "getCurrentUsername"
}, new String[] { "user" });
The implementor of the "IRoleValidator"-interface and the mapping shall be set during SMODL runtime initialization. Once the role validation is in place the runtime checks if a service method can be called before in fact calling it. This is achieved by comparing the list of roles provided by the "IRoleValidator" and the list of roles assigned to a particular method. Roles are just arbitrary strings. If there is an overlap between two sets of roles then the method can be called, otherwise an appropriate exception is thrown.
In order to set the role validation as described above, add a Java package named "org.smodl.tutorial.servlet.security" under the "Java resources" folder of the "RepositoryServiceWeb" project. Then, right click on the newly added package, select New –> Class and specify a name of the class – "SessionSecurityService".

Notice that the generated class has only one method "getRoles". If the reader will choose not to add cookie-based session management as we suggest below, the example implementation of getRoles() method can be
public String[] getRoles() {
return isSessionValid()? new String[] { "user" } : new String[] { "anonymous" };
}
where actual session validation – isSessionValid() – is left to the reader's choice.
The service relies on password authentication to grant access to the secured content. It means that the user should send her username and password to the service before she is allowed to access her profile. The service checks the username and password against the credentials it has stored. If they fail to match then the user is asked to try again. If they do match then the login is successful; the user is redirected to the main page of the service.
Due to stateless nature of HTTP the credentials are no longer known to the service when processing of the "login" method is over. The Web application then need a way to provide the service with user credentials for each consequent method call. We rely on session cookies to validate the session.
We introduce a security interface "org.smodl.tutorial.servlet.security.ISecurity" that defines 3 methods that will add, get and remove cookie from a user session. As a cookie we use "username" attribute. In order to set the interface, right click on the "org.smodl.tutorial.servlet.security" package under the "Java resources" folder and select New –> Interface and enter "ISecurity" as interface's name. Copy the code below into the interface.
We suggest the following sequence to check if the session is valid. First, getUsername() method shall be called which returns a user name, the active session is authenticated for the returned user name. If getUsername() returns null, the session is not validated.
The Web application signalizes that the user is authenticated by calling the userAuthenticated() method which adds "username" attribute to the HTTP session.
securityService.userAuthenticated(userName, new String[] { "user" } );
If the user logs out, the Web application should call the userLoggedOff() method which removes the attribute from the session. We use standard Servlet API to access the HTTP session in the Servlet Container.
Implementation of the ISecurity Interface
We will now make the "SessionSecurityService" class from "org.smodl.tutorial.servlet.security" package to implement "ISecurity"-interface in addition to "IRoleValidator"-interface described above.
Then paste in the following code into the "SessionSecurityService" class.
Implementation of the IRoleValidator Interface
We shall now add getSessionHolder() and isSessionValid() methods to the "SessionSecurityService" as listed below. Note that the getRoles() method is already in place.
public boolean isSessionValid() {
HttpSession session = sessionHolder.get();
Object username = session.getAttribute("username");
if (username != null) {
return true;
}
return false;
}
public String[] getRoles() {
if (!isSessionValid()) {
return new String[] { "anonymous" };
}
HttpSession session = sessionHolder.get();
return (String[])session.getAttribute("roles");
}
public static ThreadLocal<HttpSession> getSessionHolder() {
return sessionHolder;
}
An instance of "SessionSecurityService" class stores a name of an authenticated user in the "username" property. This property is kept in the "HttpSession" object attached to a current thread. Following the logic of implementation, the "SessionSecurityService" object returns user's roles if a user is authenticated and "anonymous" if a user is not authenticated in answer to the getRoles() method call.
Implementation of the IRepositoryService Interface
Implementation of the RepositoryService Servlet
Notice that the SmodlHttpServlet.doPost() method call commits HTTP-response. Which means that whenever the SmodlHttpServlet.doPost() is called, addition of HTTP-headers become unfeasible. If some extra headers must be set they should be added prior calling the SmodlHttpServlet.doPost().
If you need assistance in building an AJAX client that uses the service check our AJAX tutorial.