Monday, May 9, 2011

Grails Plugin Spring Security Kerberos Sample

This blog is about a simple sample application that demonstrates usage of Grails Spring Security Kerberos Plugin. It is assumed that the reader is familiar with Kerberos Authentication, Grails, Spring Security and Grails Plugin system.

The above plugin is just a wrapper on top of Spring Security Kerberos Extension. All it is doing is to handle the Spring beans assembly and integrate with the Spring Core Security Plugin.

Start with reading the documentation on Kerberos Grails Plugin and the blog on Spring Kerberos Extension. As you can see there isn't much configuration to do in Grails Kerberos Plugin. Just the Keytab file path and Service Principal Name are required.

Read the blog on Kerberos Extension carefully and create the Keytab file for the Service Principal (Your AD administrator would do it). The bulleted check list found towards the end of the Kerberos Extension blog is very helpful to make sure that everything is done properly.

What is the Grails Plugin is all about?
There is a section "Configuring Spring Security" in the above blog. The plugin has all those configurations taken care of except the URL mapping. So you don't have to do it in your Grails application

How do I do the URL mapping?
Just use one of the options provided by Spring Security Core Plugin (@Secured, Requestmap etc.)

What are the other catches?
Typically when Kerberos SSO authentication is used, no user details would be stored in the application database. In Spring Security the user details are loaded into the security context by the "userDetailsService" bean. This is demonstrated by the usage of "dummyUserDetailsService" in the Kerberos Extension sample.
So in the Grails application the following bean should be present in conf/spring/resources.groovy. Otherwise Security domain objects (User, Role etc.) should be in use

beans = {
userDetailsService(com.mycompany.myapp.MyUserDetailsService)
}

Now about the sample application.
This is how I had created the application
> grails create-app grails-spring-security-kerberos-sample
> grails install-plugin spring-security-kerberos
And added is main.gsp and index.gsp.

** Consider "mymachine" as the CNAME/Hostname of the machine being used deploy the application and "mydomain" is the domain controller
So the Service Principal should be "HTTP/mymachine.mydomain.com@MYDOMAIN.COM"
The name of the keytab file could be anything.

Let's start Config.groovy configuration.

// Kerberos related
grails.plugins.springsecurity.kerberos.ticketValidator.servicePrincipal='HTTP/mymachine.mydomain.com@MYDOMAIN.COM'
grails.plugins.springsecurity.kerberos.ticketValidator.keyTabLocation='file://D:/keytabs/myapp.keytab'   //put the keytab file in a secure location


// Spring Security Core related (You may use other options too)
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
grails.plugins.springsecurity.interceptUrlMap = ['/**': ['IS_AUTHENTICATED_FULLY']]

What about KDC configuration?
Create a krb5.conf file and point to it using -Djava.security.krb5.conf JVM option. A sample can be found in the root folder of the source.
In Windows a krb5.ini file (exact name only) can be placed in C:/Windows folder

That's it.
Now run the application
Access it from another machine in the same domain using the fully qualified name of machine where application is running (localhost will not work, also using IP address from another machine).
If the authentication is successful, the NT user name will be displayed in home page.

Download the source (Eclipse/STS)

Just unzip it, create the Keytab file for the Service Principal and change the Config.groovy entries. You are ready to go.

My Environment Details
  • app.grails.version=1.3.7
  • plugins.spring-security-kerberos=0.1
  • JDK 1.6.0_23
  • Windows XP
  • Sample worked with embedded server (run-app) and apache-tomcat-7.0.10
  • Windows 2003 Server (Used a local domain controller setup [i.e. two XP and one 2003])
  • IE 6 & 7, FF 4.0 and Chrome 11
  • STS 2.5.2 (Springsource Tool Suite)
Error when "userDetailsService" bean is not Present
ERROR [/grails-spring-security-kerberos-sample].[default]  - Servlet.service() for servlet default threw exception
java.lang.NullPointerException: Cannot get property 'clazz' on null object
at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56)
at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:156)
at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:235)
at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:50)

Hope this blog helps you implement Keberos based security in your Grails application.


Monday, June 7, 2010

Grails Evaluation

Recently at work, I have evaluated Grails Framework as part of larger initiative to choose a better framework that focuses on productivity gains without compromising other features expected from a good framework. Finally we chose Grails as the framework to be adopted internally for agile development. Here is why:

The published tag lines of the Grails framework are Rapidness (Productivity), Dynamic (Agile) and Robustness. While principles like DRY (Do not Repeat yourself), CoC (Convention over Configuration) and Code Generation etc provides the Rapidness; and Groovy, Scaffolding and Automatic Dependency Injection makes it Dynamic; and ultimately the fact that Grails artifacts are compiled to Java class files that make use of well proved libraries like Spring, Hibernate, Sitemesh etc. and runs in JVM provides the much needed Robustness.

On top of the core Grails library there are myriads of plug-ins (modular Grails extensions that enhance core Grails features and brings new ones to it) that brings reusable components/functionalities to Grails and greatly reduces the total effort required to create applications.

Grails has its own DSL based ORM mechanism (GORM); Controllers, Filters and Interceptors, Tag libraries etc. for Web layer; Pluggable AJAX provider; a Service Layer with automatic dependency injection and optional Java service use; excellent internationalization support with messages.properties files generated for multiple languages and convention based keys; very helpful error display where actual code snippet that caused the error is quoted; out of the box support for REST and plug-ins for SOAP web services; integration tests are created when controllers are generated; and Grails has embedded database and servlet container for development environment.

The hands on exercises that we have carried out using Grails revealed its main offering: productivity. It took no more than 10 minutes to setup the development environment, another 5 minutes to create a ‘Hello World’ application. By spending less than 30 minutes we were able to create a fully functional CRUD application (on a single entity). With the experience gained from creating these two applications, we were able to create a fully functional sample Shopping Cart application with an RDBMS within 1.5 days!!. Within 10 minutes security was enabled using Acegi plug-in.



What good a framework will do if it accompanies performance penalty for improving the productivity? Grails has no such issues, though it doesn’t provide significant performance improvement. It did work pretty reasonably under varying loads.

Adopting any new language and framework involves learning curve, sometimes it can be a hindrance. Groovy, the language behind Grails, too involve some learning curve, but relatively easy as it follows existing idioms.

Grails is a good framework that delivers what it promises and can be adopted for enterprise use. If adherence to full-stack JEE and usage of Java language is not a must, then Grails is an ideal framework that offers full application-stack features

Environment Details

app.grails.version=1.2.2
app.servlet.version=2.4
plugins.acegi=0.5.3
plugins.hibernate=1.2.2
plugins.tomcat=1.2.2
Java 1.6

If you are planning to learn Grails and use it, you will find the necessary guidelines from the various articles at Mastering Grails at DeveloperWorks

I will try publish more specific articles on Grails in coming days (lot many from others already exists though)

Friday, September 11, 2009

Spring JNDI Bind Utility for Unit Tests


Spring does provide JndiTemplate class for JNDI lookup through spring configuration. But there is not such convenience class for binding Objects to jndi server through configuration.
Through there are some classes like SimpleNamingContextBuilder that can be used programmatically but not via configuration (at least as it is).

Here I am presenting a utility class that be used to register jndi objects via Spring configuration.
For demo purpose commons-dbcp classes are used as resources to be bound to the jndi server.

The JNDI server used is file based RefFSContextFactory from sun. Any other JNDI Server would also suffice

Prerequisites
spring-core-2.5.6.jar
spring-beans-2.5.6.jar
spring-context-2.5.6.jar
providerutil.jar (referenced from fscontext)
The following jars are required for the demo sample only

I am presenting two version of the JNDI Binder utility class; one extends JndiTemplate and the other one extends InitialContext.


Binder Utility based on Spring's JndiTemplate class: JndiBinderTemplate
package in.spring.jndi.util;

import java.util.Iterator;
import java.util.Map;
import javax.naming.NamingException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jndi.JndiTemplate;

/**
* A Spring specific utility class to register objects to a jndi server through spring configuration
* Sample usage with file based jndi server
*
* Instead of using interfaces InitializingBean and DisposableBean, @PostConstruct and @PreDestroy
* annotations or init-method can be used
* @see org.springframework.jndi.JndiTemplate
* @author Vijesh
*
*/
public class JndiBinderTemplate extends JndiTemplate implements InitializingBean, DisposableBean  {

private Map jndiObjects;

public Map getJndiObjects() {
return jndiObjects;
}

public void setJndiObjects(Map jndiObjects) {
this.jndiObjects = jndiObjects;
// if life cycle interfaces are not available
// call loadJndi(); here
}

@Override
public void afterPropertiesSet() throws Exception {
loadJndi(); 
}


public void loadJndi() {
System.out.println(" start binding Objects to JNDI server ");

if(jndiObjects != null && !jndiObjects.isEmpty()) {

Iterator itr = jndiObjects.entrySet().iterator();

while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();

try {
rebind((String) entry.getKey(),entry.getValue());
} catch (NamingException e) {
System.out.println(" Binding "+entry.getKey()+" is failed with error: "+e.getMessage());
}  
}

System.out.println(jndiObjects.size()+" Objects bound to JNDI server ..");
}
}


@Override
public void destroy()  throws Exception {
clearJndi();
}


public void clearJndi() {
System.out.println(" unbind the Objects from the JNDI server  ");

if(jndiObjects != null && !jndiObjects.isEmpty()) {
Iterator itr = jndiObjects.keySet().iterator();

while (itr.hasNext()) {
String jndi = null;
try {
jndi = (String) itr.next();
unbind(jndi);
} catch (NamingException e) {
System.out.println(" Error in unbinding "+jndi);
e.printStackTrace();
}
}
}
}
}

The Spring configuration for the above class with some sample resources used to bind to the JNDI server is:



 


com.sun.jndi.fscontext.RefFSContextFactory
file:/




















Now the look up from the jndi consumer classes using will happen as expected. For example the following code would work perfectly fine.

/**
* Jndi lookup using Standard mechanism
*/
public void testJNDIBinder() {

System.out.println("\n in testJNDIBinder ");

System.setProperty("java.naming.factory.initial", "com.sun.jndi.fscontext.RefFSContextFactory");
System.setProperty("java.naming.provider.url", "file:/");

try {
Context cxt = new InitialContext();

Object obj1 = cxt.lookup("jndi/sDS");
System.out.println(" obj1 "+obj1);
Object obj2 = cxt.lookup("jndi/pDS");
System.out.println(" obj2 "+obj2);

System.out.println(" Look up test is successful.... ");

} catch (NamingException e) {
System.out.println(" Look up test failed.... ");
e.printStackTrace();
}
}


Binder Utility without Spring dependency: JndiBinderContext

The second class is very much similar to the one shown above except for it extends the class InitialContext

package in.spring.jndi.util;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
* A standard utility class to register objects to a jndi server through spring configuration
* Sample usage with file based jndi server
* @see javax.naming.InitialContext
* @author Vijesh
*/
public class JndiBinderContext extends InitialContext {

public JndiBinderContext() throws NamingException {
super(); 
}

public JndiBinderContext(Hashtable env) throws NamingException {
super(env);
}

// Rest is almost same as JndiBinderTemplate class, refer the source code for details



Another main difference is in passing the environment properties. In this case they are passed as constructor arguments (it is so in InitialContext)


    




com.sun.jndi.fscontext.RefFSContextFactory
file:/


















Please note that both the classes should be loaded lazily.

It's really unfortunate that Spring didn't provide a similar utility class. Why didn't it occurred to them when they created JndiTemplate class for lookup purpose?

Download the source (eclipse project)
The dependent libraries listed in the prerequisites should be downloaded separately and added to the project.

Even though I have used particular version of each dependent libraries, it doesn't mean that the utility will work only with that. As you can see, it is a simple class and should work with the earlier releases of the dependent libraries.

Friday, February 20, 2009

JavaFX CRUD Application

Well, I too jumped into the JavaFX bandwagon. Since I have good exposure to Swing, naturally I got excited by the new Rich Client Platform offering from Sun.

Most of of the examples using JavaFX available in Internet are demonstrating the graphic and animation capabilities of JavaFX and very few concentrates on Enterprise application needs. Yes I understand that one of the objective of JavaFX is to compete with other RIA/RCP offerings and the enterprise data centric application needs are already taken care of by Java Swing and web technologies.

Since my experience is mainly in developing data centric applications in enterprise world, I thought of creating a sample CRUD application that would use components from both JavaFX and Swing, former being the runtime and having major presence.

http://www.learntechnology.net/ has nice set of sample applications using most of the commonly used technology/frameworks and all of them are based on the same data model (Employee-Department). I liked the idea behind this site and decided to develop my JavaFX example using the same model, infact it uses the data layer from one of the samples there and make contribution.



Please find the lesson and source at http://www.learntechnology.net/content/javafx/javafx.jsp

Click the button to start the above example using Java Webstart: