Skip to main content

How to integrate Container security in a web application and propagate it to EJB Layer.

Normally an enterprise application has a web tier and a business tier (Most probably EJB in the case of J2EE).The security requirments for such an application in general will be this "Only an authenticated and authorized user should be able to access the protected part of the application" This includes both dynamic (jsp pages) and static content like HTML files.

If the user has the rights for the web page then based on his role he should be restricted to invoke an ejb method.That's even if he has access to a page he should be able to execute only those business operations for which his role is given access.



To satisfy the above requirement we have to have security at 2 levels . One at the web container side and other at the ejb container side.


The rest of the post explains how we can do that in JBoss 4.2.2
See my old post on securing an EJB. Once the EJB is secured, next step is to secure the web application.
The web.xml is given below

<servlet>
<servlet-name>securess</servlet-name>
<servlet-class>com.prem.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>securess</servlet-name>
<url-pattern>/central/secured</url-pattern>
</servlet-mapping>

<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted to Secure role</web-resource-name>
<description>Declarative security</description>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>secure</realm-name>
<form-login-config>
<form-login-page>login.html</form-login-page>
<form-error-page>login.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>

This shows that /admin pattern is protected and it requires admin role for access. login.html will be the form used to collect the login credentials and the authentication method is FORM. Once this is done we have to configure a security realm so that the container will use this relam for authentication. We can do this in jboss by configuring a relam named secure . This is done in the login-config.xml

The login-coinfig.xml entry is given

<application-policy name = "secure">
<authentication>
<login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
<module-option name = "dsJndiName">java:/mysql</module-option>
<module-option name = "principalsQuery">select passwd from users where USERID=?</module-option>
<module-option name = "rolesQuery">select role,'Roles' from user_roles where user_id=?</module-option>
</login-module>
<login-module code="org.jboss.security.ClientLoginModule" flag="required" />
</authentication>
</application-policy>

The use of ClientLoginModule is required to propogate the caller threads identity to the EJB tier.ClientLoginModule is critical in propagating the Subject from the web to the ejb tier.

In a simple approach it makes sense to use j_security_check for doing the Container authentication.But j_security_check is not very flexible and doesn't have a straight forward way to collect some other
information as part of login form. j_security_check is appropriate for simple logins required for simple web applications. For a complex web application which requires more than username and password from a login form, we have to go for programatic web authentication.

First i will explain the j_security_check approach

<form action="j_security_check" method="POST" >
<input type="text" name="j_username" >
<input type="password" name="j_password">
</form >


When ever a secured page is accessed container will intercept and forward the login.html. If the login is successful the container will redirect to the protected resource. Problem with j_security_check is that you cannot access the login.html directly. You have to access the protected resource and let the container show the login.html. If you directly access the login,html you will get exceptions on submitting the form. There are work arounds for this like providing a filter on j_security_check or submitting to another servlet , get all required parameters in that servlet and from there redirect to j_security_check.All the above has limitations and are not good solutions. The filter doesn't work in the case of tomcat.So the bottomline is go for active authentication(means writing our own
class which does the authentication and inform the container about it).

To do the active authentication follow the below steps.
Instead of j_security_check use own servlet

<form action="/Secure/central/secured" method="POST" >
<input type="text" name="j_username" >
<input type="password" name="j_password">
<input type="text" name="companycode">
</form >

In the doPost of the servlet you may code like this.

WebAuthentication webAuthentication=new WebAuthentication();
boolean stat=webAuthentication.login(user, pswd);
if(stat) {
String referer=req.getHeader("Referer");
System.out.println("referer = "+referer);
res.sendRedirect(referer);
}else {
res.sendRedirect(req.getContextPath()+"/errorlogin.html");
}
Important point to note is that here we are using the WebAuthentication class provided by JBoss from 4.2.2 onwards.

Summary

  • Use ClientLoginModule to propagate client identity to the server.This is applicable for both web and standalone clients.
  • Use WebAuthentication for programmatic authentication
  • Better to use your own servlet than using j_security_check

Comments

Anonymous said…
This comment has been removed by a blog administrator.

Popular posts from this blog

Using Database login Module in JBoss

This post is a detailed description on how to use the database login module in JBoss with a J2EE Application. Scenario There is a EJB and we want to restrict the access to this ejb's method to an authenticated user having a particular role. The EJB is accessed from a standalone Java Client using Remote Lookup. Implementation The EJB is HelloSSB and the roles allowed are admin and user. First step is to write the EJB The source code is given below. This is a stateless session bean. package com.prem.ejb; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.annotation.security.RolesAllowed; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.jboss.annotation.security.SecurityDomain; @Stateless @SecurityDomain ("helloworld") public class HelloSSB implements HellioIntf{ @PersistenceContext(unitName = "EntApp") EntityManager em; @Reso...

Design Patterns

A note on Design patterns Many times we can see ourselves looking for design patterns to fit the design of a requirement. Of course if the requirement is simple enough to apply any existing design pattern we should do so. This will save us valuable time. In my opinion it is better not to worry about which pattern to apply.But concentrate on the three basic Object oriented principles. 1) Encapsulate what varies 2) Prefer composition over inheritance 3) Program to an interface not to an implementation. If we approach the design with these principles in mind , we don't have to search for patterns. Pattern will emerge itself. Once we apply these principles, we can definitely look whether any of the existing patterns can solve the issue better than the way we thought of. This way our thinking process will improve tremendously and at times we may end up creating a solution which may be better than any available design patterns.

Load Balancing

Why do you need to load balance ? Here i will put forward the various options available for web load balancing. Before we go into that , let us first examine why do we need load balancing after all.Consider you develop a website and is available to the public.If the application is served from a single webserver then there is a high chance that the machine will be overwhelmed if the usage of the application increases. This may result in users experiancing unusually high response times or in worse case the machine can come to a halt.So you need some mechanism to distribute the load across different machines,without the client having to swich address. There are many widely used approaches. The most common ones are DNS based load balancing Software load balancing Hardware load balancing DNS based Load Balancing Here the DNS server is configured in such a way that it returns different IP addresses for various requests to the DNS server for a particular domain name. The DNS server may contai...