Friday, November 7, 2008

Auto SSL Switch Over Issue

To protect a web resource typically we add a security constraint CONFIDENTIAL in the web.xml in the case of Java Technology. That means that this resource is protected and can only be accessed via HTTPS. How this works is this way. Browser sends the request to the resource . Container intercepts and sends a redirect url which is the https URL. Browser again sends the request via HTTPS. The advantage is this mechanism will do automatic switch over of protocols. Hence by simply changing the configuration we can make which part is http and which should be https.
But the issue is when the application is accessed via a reverse proxy. In this scenario the automatic protocol switch over will contain the IP or domain name of the internal server and not of the proxy. Hence we may have to do the http to https switch over using java script from the browser. So this defeats the whole purpose of CONFIDENTIAL element. I haven't seen any where in the web.xml spec an element to specify the address or domain of the front end host . In this case reverse proxy. I think this is a serious limitation. In my view this element should be added to the JSP / Servlet spec and the web.xml should be updated.

Performance Improvement & Scalability


The best approach to improve the performance and scalability is to pre calculate the logic and cache the results.

All computer systems are surviving heavy loads due to caching.
It is best to cache at DB, cache web pages at the reverse proxy and of course let browser cache the javascript , css and images.



The user request may be anticipated and the system execute the logic and store the information in cache.

When a request with matching parameter arrives just serve the information from the cache. This is particularly true for availability searches in the case of hotels, airlines etc.



The one word mantra : CACHE IT.

Friday, May 16, 2008

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

Wednesday, May 7, 2008

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;
@Resource SessionContext ctx;
@RolesAllowed ({"admin","user"} )
public void hello() {
System.out.println(ctx.getCallerPrincipal().getName());
if(ctx.isCallerInRole("admin")) {
System.out.println("hello admin");
Book book=new Book();
//book.setId("1");
book.setName("J2EE blue Prints");
em.persist(book);
}else if(ctx.isCallerInRole("user")) {
System.out.println("hello User");
}else {
System.out.println("UNAUTHORISED ");
}
}
@PreDestroy public void close() {
System.out.println(" in predestroy ");
}
}



Here the annotation @SecurityDomain ("helloworld") indicates that this EJB is secured by the helloworld security domain.@RolesAllowed ({"admin","user"} ) indicates that the the method hello is accessible only to admin and user roles.
With this the EJB is ready. You can ignore the entity bean used in the EJB.
Edit the jboss.xml and provide a JNDI name for the EJB.

Example


<?xml version="1.0" encoding="UTF-8"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>HelloSSB</ejb-name>
<jndi-name>com.prem.Hello</jndi-name>
</session>
</enterprise-beans>
</jboss>



Now we need to configure the security domain in JBoss.
Edit the login-config.xml in the conf directory and add an entry like this.


<application-policy name="helloworld" >

<authentication>
<login-module flag="required" code="org.jboss.security.auth.spi.DatabaseServerLoginModule">
<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 userid=?</MODULE-OPTION>
</LOGIN-MODULE>
</authentication>
</APPLICATION-POLICY>




This sets up a security domain in JBoss which will use the DataBaseServerLoginModule to authenticate and authorize any requests to the resource protected by this domain.
The above steps completes the server side setup.
Now we have to write the client and we want to propagate the client side login credentials to the server.For this jboss provides a ClientLoginModule. This login module does not do any authentication (client side ), it just passes the login information to the server.
Code for the client is given below

package com.prem.client;

import java.util.Iterator;
import java.util.Properties;
import javax.naming.*;
import org.jboss.security.auth.callback.SecurityAssociationHandler;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import java.security.Principal;
import com.prem.ejb.HellioIntf;

public class EJBClient {
static String user="prem";
static String password="prem";
public static void main(String[] args) throws Exception {

SecurityAssociationHandler handler = new SecurityAssociationHandler();
Principal userPrincipal = new Principal() {
public String getName() {
return user;
}
};
handler.setSecurityInfo( userPrincipal, password);
LoginContext loginContext = new LoginContext( "hello", ( CallbackHandler ) handler );
loginContext.login();
String jndiName="com.prem.Hello";
final Properties p = new Properties();
Context ic = new InitialContext();
System.out.println("about to look up jndi name " + jndiName);
Object obj = ic.lookup(jndiName);
System.out.println("lookup returned " + obj.getClass());
HellioIntf foo = (HellioIntf) obj;
foo.hello();
}
}
For this client to work it has to use the ClientLoginModule and its configured through the JAAS config file
Content of the JAAS config file is given below.

hello {org.jboss.security.ClientLoginModule required;};



Now add all jars in jboss client folder to the classpath.Also add jbosssx jar to the classpath.
This completes the entire process.
Do create the tables mentioned in the login-config.xml mentioned above before testing the program



Wednesday, April 30, 2008

An interesting difference between Oracle and MySQL

This is a very interesting and important difference between the Default settings of oracle and mysql isolation levels.

Default Isolation Level for Oracle = READ COMMITED
Defautl for MySQL = REPEATABLE READ

J2EE Container Security in Applications

Introduction

Using J2EE Container security is the first step towards designing a secure and portable J2EE application.

The integration of Container security with an application is easy but requires some amount of knowledge and research. The main reason for this is various J2EE application server providers gives us only a limited amount of login modules by default.
For example an Active Directory authentication is a standard requirement but not all J2EE Server vendors provide this.But many major vendors provide this login module . The bottomline is we may be required to write our own login modules for many standard services. Writing our own login module is not difficult .Writing a custom login module will not be covered in this post.This post is about integrating a DB login module to an application deployed in JBoss Server.
In this post i am only giving the steps without eloborating on each of the steps.

5 Steps
  1. Identify the EJB that you want to secure.
  2. Add the annotation @Securitydomain and give the name of the domain which will provide the security.
  3. Add @RolesAllowed annotation and define which roles can access the EJB methods
  4. In the jboss login-config xml add a security domain entry
  5. Configure the DatabaseServerLoginModule as the liogin module. This will allow us to use authenticate and authorise the user and roles from a database. This module is provided by JBoss , so only thing left is to tell this module the tables to be used.
That's all. Now try invoking the ejb methods without providing a user and password in the JNDI properties. You should get an authentication exception.Now provide a valid user and password and if that user is mapped to a role then the ejb invocation will be successful.

Friday, February 22, 2008

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 contain say 5 IPs for a particular domain name and on a round robin basis it can different IPs for different requests. The draaw back with this approach is it cannot do a weight based routing as it has no information on which server is heavily loaded. It can only do a round robin based load balancing. This would be sufficient for many websites.

Software Load Balancing

In this mechanism another webserver or some software plugins does the load balancing.
In the case of weblogic many plugins are available for various web servers. WLProxy plugin from weblogic is available for IIS, Apache etc. This plugin can load balance the web requests if the web application is deployed in a cluster in a weblogic server. The advantage with software load balancing is that it can do weigh based load balancing also. It can detect if any server in the cluster has go down . The plugin can remove that address from its algorithm. Also it can do server affiinity.

Hardware load balancing

In this mechanism a hardware like F5 Big IP load balancer can be used to do the load balancing.Hardware load balancers has mechanisms to load balance SSL requests also.
Also many such load balancers has the capability to compress a response. This can result in good response time from a low bandwidth environment.

Which load balancer to use is a decision to be taken based on the specific application requirements and projected usage.

Thursday, January 24, 2008

ORACLE BUYING BEA

BEA has announced that they have reached an agreeement with oracle
on the purchase of BEA by Oracle.
I think BEA with its excellent application server Weblogic is the looser here.
Oracle has their own Application server and SOA intergration platforms.
So what are they going to do with Weblogic . Will they promote it or rename it ?