Friday, February 29, 2008

Single Sign on with glassfish

Holy cow check out this little nugget taken from the GlassFish manual:


User Authentication for Single Sign-on

The single sign-on feature of the Application Server allows multiple web applications deployed to the same virtual server to share the user authentication state. With single sign-on enabled, users who log in to one web application become implicitly logged into other web applications on the same virtual server that require the same authentication information. Otherwise, users would have to log in separately to each web application whose protected resources they tried to access.

An example application using the single sign-on scenario could be a consolidated airline booking service that searches all airlines and provides links to different airline web sites. Once the user signs on to the consolidated booking service, the user information can be used by each individual airline site without requiring another sign-on.

Single sign-on operates according to the following rules:

  • Single sign-on applies to web applications configured for the same realm and virtual server. The realm is defined by the realm-name element in the web.xml file. For information about virtual servers, see the Sun Java System Application Server Platform Edition 9.0 Administration Guide.
  • As long as users access only unprotected resources in any of the web applications on a virtual server, they are not challenged to authenticate themselves.
  • As soon as a user accesses a protected resource in any web application associated with a virtual server, the user is challenged to authenticate himself or herself, using the login method defined for the web application currently being accessed.
  • Once authenticated, the roles associated with this user are used for access control decisions across all associated web applications, without challenging the user to authenticate to each application individually.
  • When the user logs out of one web application (for example, by invalidating the corresponding session), the user's sessions in all web applications are invalidated. Any subsequent attempt to access a protected resource in any application requires the user to authenticate again.

The single sign-on feature utilizes HTTP cookies to transmit a token that associates each request with the saved user identity, so it can only be used in client environments that support cookies.

To configure single sign-on, set the following properties in the virtual-server element of the domain.xml file:

  • sso-enabled - If false, single sign-on is disabled for this virtual server, and users must authenticate separately to every application on the virtual server. The default is true.
  • sso-max-inactive-seconds - Specifies the time after which a user's single sign-on record becomes eligible for purging if no client activity is received. Since single sign-on applies across several applications on the same virtual server, access to any of the applications keeps the single sign-on record active. The default value is 5 minutes (300 seconds). Higher values provide longer single sign-on persistence for the users at the expense of more memory use on the server.
  • sso-reap-interval-seconds - Specifies the interval between purges of expired single sign-on records. The default value is 60.

Here is an example configuration with all default values:

<property name="sso-enabled" value="true"/>
<property name="sso-max-inactive-seconds" value="450"/>
<property name="sso-reap-interval-seconds" value="80"/>

How sweet is that?



Thursday, February 28, 2008

MD5 Encryption Java style

Here is a little nugget you might enjoy how to do some MD5 Encryption with Java pretty easy really.  Mostly taken from this book:



package test.md5.encrypt;


import junit.framework.TestCase;

public class TestMessageDigest extends TestCase {
private static String[] hexDigits = {"0", "1", "2", "3",
"4", "5", "6", "7",
"8", "9", "a", "b",
"c", "d", "e", "f"};
public void testEncrypt(){
MessageDigest md = null;
DigestInputStream dis = null;
String digestedString = null;
md = MessageDigest.getInstance("MD5");
ByteArrayInputStream bis =
new ByteArrayInputStream("password".getBytes());
dis = new DigestInputStream(bis, md);

byte[] bytes = new byte[1024];;
md = dis.getMessageDigest();
byte[] digest= md.digest();

digestedString =byteArrayToString(digest);
} catch (Exception e){
private String byteToHexString(byte aByte){
int n = aByte;
if (n < 0) n = 256 + n;
int d1 = n/16;
int d2 = n%16;
return hexDigits[d1] + hexDigits[d2];
private String byteArrayToString(byte[] bytes){
String result = "";
for (int a = 0; a < bytes.length; a++){
result += byteToHexString(bytes[a]);
return result;

Not too bad is it?  Thanks to Jamie Jaworski and Paule Perrone for authoring that book (heh, I actually got in on clearance for $15.00) not too shabby...



Saturday, February 23, 2008

a wasted week

So, I did say I hated ldap right?  After fighting and fighting with I finally gave in and tried the JDBCRealm with Glassfish's security configuration.

So much nicer.  There is a brilliant post here that explains how to do it.  The only comment I would have is that you can sent the encryption to none instead of MD5 or something else. 

So, yeah I pretty much wasted a week trying to do things the "right" way.  I'm totally digging the JDBC Realm though.  It works just the way you think it should.




Thursday, February 21, 2008

Container Managed LDAP

<sigh> will these ldap posts ever end?

So now that I have authentication working, I want to be able to register users now.  So how can I save users easily to my ldap server?  Well I figured there had to be an easy way to get a container managed instance of the server, low and behold I found this post on making a container managed LDAP from a Java Evangelist.

Once you follow all of those instructions, what is the best way to get access to it?  With Spring of course!

It's as simple as injecting this into your bean

<bean id="ldapServer" 
<property name="jndiName">
<property name="resourceRef">

Couldn't be easier. 

Putting it all together

So, now that I have my ldap server working (more or less).  I need to use it to authenticate with, this turned out to be surprisingly easy with GlassFish.  I created a new LDAP Realm like this:


The "assign group" property was  a bit confusing - basically it is just a value that you map you application to in the web.xml and the sun-web.xml this is an exampl of how it could be done using the webusers as the value of the "assign group" property.


<web-resource-name>Faces Servlet</web-resource-name>



The last bit of magic is the login form:

<form action="j_security_check" method="post">
<table border="0" cellspacing="0" cellpadding="0">
<p>User ID<br/>
<input type="text" name="j_username" value="" size="10"/>
<input type="text" name="j_password" value="" size="10"/>
<td style="padding-bottom: 10px;">
<input type="submit" value="Log In"/>

And that is how you can authenticate.  Now if you remember I'm using JSF to manage this and that is clearly not a jsf form.  So this is how I decided to make it work (and there are other options) it is not without problems mind you, JSF makes a lot of things better but in so doing messes up a lot of old conventions.

I have decided to work on the assumption that users are going to navigate to my web site by saying great web  I have the welcome page in a "protected" area so that by navigating to the welcome page you will get kicked out the the registration screen if you are successful then you get sent to the welcome page which does a jsp:forward to the welcome page through a faces context.  It is overly complicated I think but we have to make sure that the faces context is initialized correctly.

Thursday, February 14, 2008


So I'm not a big fan of LDAP of any kind.  It could entirely be out of ignorance I will admit to that.  It seems very out dated when the info you store can be done SOOOO much easier in a database.


Having said that it seems all "real" applications have an LDAP server back end.  So, tonight I have decided that this is the night when flyingspheres has a working LDAP server.  Not that I really need one mind you it is really just me for the most part, but to really play with security modules in Java you need to have the container working together with an ldap server.

So here we go...

I will be referencing lots of sites to get this work done.  Mostly cause me not so smart when it come to LDAP...

OpenLDAP comes down from the friendly synaptic manager.  Once you get that installed (very easily mind you) you get a new config directory at /etc/ldap which looks like this:


-rw-r--r-- 1 root root  333 2007-04-27 10:19 ldap.conf
drwxr-xr-x 2 root root 4096 2007-12-03 14:05 sasl2
drwxr-xr-x 2 root root 4096 2008-02-08 18:38 schema
-rw------- 1 root root 4340 2008-02-14 21:56 slapd.conf


Now, when I installed OpenLDAP I think my server wasn't named very well so if you were to try and connect to me (and I opened a hole in my firewall) you would see the DN of nodomain.  Heh, is that cool or what?

So first order of business how do I change that?

Sprinkled liberally throughout our slapd.conf file is a reference to nodomain.  This is no doubt a problem.  Before we go mucking around it let's back up that file first... 

... ok backup complete.

Now let's go through and change the cn="nodomain" to cn="flyingspheres",cn="com"  (make sure you get them all).

Ok, that's done.

YoLinux points out that the database our ldap server is under the directory attribute.  By default uBuntu put mine here: "/var/lib/ldap".  Common sense says that's where the nodomain database lives so I'm going to move it somewhere else.  if you look in that /var/lib/ldap directory there is a lot of stuff there.  I wonder what it all is... oh well.... so made my new directory and pointed slapd.conf to it.  I'm hoping that when I restart slapd (openLdap) all that stuff will be created in my new directory.  Once the directory is created and slapd points to the correct location it's time for a restart.  (upon restart there was no love.... my directory was empty... maybe that's ok).

So after about 20 minutes of poking around looking through the OpenLdap link things started working.... I can connect there are db files in the directory defined for the db.  I initially created an ldif file with only the admin user and that worked pretty well, although connecting went through anonymous bind only.


So, many minutes later (maybe an hour or so).  There is a mildly intuitive relationship between the object classes and attributes to what you are wanting to store in your LDAP.  I'm sure if someone reading this knows what they're doing they're laughing now.  You need to pull in the objectClasses that you want into your LDIF file and then add the attributes you care about (and the ones that are required, hopefully they're the same).

I ran the ldapadd probably 50 times trying to figure out the right combination.


Like I said I'm not a real big fan of LDAP...



Tuesday, February 12, 2008

Begin Again

So, I'm starting a new project. 

It never ceases to amaze me how difficult java web applications are to setup.  A lot of it is because of all the different frameworks we get to choose from.  This project appears to be going to use Ice Faces (a JSF implementation/extension), Facelets some level of Spring Integration, possibly JPA or Hibernate.

I played around with RichFaces and facelets a few months ago and was able to lean on the JBoss IDE for some of the configuration, but since I'm using Ice Faces this time I don't want all of the extra stuff that comes with the JBoss IDE.

So we get to start from scratch.  The documentation is pretty decent on what needs to be added to the web.xml and faces-config.xml to get facelets working correctly.  But after that where do you start?  I guess the best place is always the beginning so let's code up the index.html page (always a good place to start).

As you know for faces to work you need to be working w/in a faces context so this is a really good places to initialize the faces context let's make a silly little index.jsp page that simply forwards us inside the context:


<%@ taglib uri="" prefix="h" %>
<%@ taglib uri="" prefix="f" %>
<title>My Title</title>
<jsp:forward page="pages/login.jsf" />


So, that's easy enough.  But, with Facelets we don't want to really be writing jsf or jsp pages.  Clearly we are forwarding to a jsf page though what gives?  We create a url-pattern mapped to a Faces Servlet so any request to our url pattern (*.jsf) get's routed through the faces context.  One last thing we need to make sure our faces.DefaultSuffix is linked to *.xhtml pages.  So our pages/login.jsf page will land on the pages/login.xhtml page.   Remember with JSF it is all about the faces context stay in the context and you will be ok. This is why (IMHO) if you're doing AJAX you really need to use a framework like RichFaces or IceFaces.  You're just asking for death by a million cuts to go any other route.

So I got all my xhtml files created the web.xml and faces-config.xml are all tweaked out and guess what the dang thing didn't work.  I kept getting this error:


at com.sun.faces.config.ConfigureListener$InitFacesContext.getViewRoot(
at com.sun.faces.util.MessageFactory.getMessage(
at com.sun.faces.util.MessageUtils.getExceptionMessageString(
at com.sun.faces.util.Util.createInstance(
at com.sun.faces.config.ConfigureListener.configure(
at com.sun.faces.config.ConfigureListener.configure(
at com.sun.faces.config.ConfigureListener.contextInitialized(
at org.apache.catalina.core.StandardContext.listenerStart(
at org.apache.catalina.core.StandardContext.start(
at com.sun.enterprise.web.WebModule.start(
at org.apache.catalina.core.ContainerBase.addChildInternal(
at org.apache.catalina.core.ContainerBase.addChild(
at org.apache.catalina.core.StandardHost.addChild(
at com.sun.enterprise.web.WebContainer.loadWebModule(
at com.sun.enterprise.web.WebContainer.loadWebModule(
at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(
at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(
at com.sun.enterprise.admin.event.AdminEventMulticaster.invokeModuleDeployEventListener(
at com.sun.enterprise.admin.event.AdminEventMulticaster.handleModuleDeployEvent(
at com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(
at com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(

This seems to be a pretty nasty error, all it is really saying is "Hey I somebody is referencing a class I don't know anything about".  This is probably java's biggest criticism happening right here on my laptop.  I think there are a total of 16 jars I needed to get my very simple page to work here.  Don't get me wrong I'm most thankful to the people who wrote them.  But man it is sure a pain to be trying to figure out what you need and what you don't.

I actually opted for the shotgun approach.  I ended up taking a demo app that comes with Ice Faces and pull out all of the jars from the demo and add them to my project.  Not very accurate but it did fix the problem.

That's enough for tonight.  I'll let you know how it goes.

By the way I got the ice faces demo apps running here:



Tuesday, February 05, 2008

More Recovery

I certainly don't understand the intimate details of all the parts and pieces of the different technologies or applications that I use sometimes.  I have an intermediate level understanding of a lot of the parts such as Apache.  Through trial and error I had figured out how to configure it to do what I wanted it to do.  The old server had MOD_JK installed and would forward some requests over to my GLASSFISH server.  Due to a lack of understanding I had gone through the exercise of compiling apache and mod_jk myself to get it all working.  And I was pretty happy with that, he advantage of doing that is that you know exactly where all the binaries and configuration is and where it's located.

With this version of the server I'm (trying) to use the synaptic package manager and haven't had to compile anything yet.  I simply clicked on Apache in the Synaptic Package Manager and it installed a working version- very simple, very painless.  The configs and htdocs are a bit scattered but I found them eventually.  MOD_JK came down through the synaptic package manager as well.  So what do we need to do to get it all working?  There are several posts that are very helpful:

Amy Roh's from Sun

Jean-Francois Arcand's from Sun


Amy Roh's blog is laid out pretty clearly

Step 1) install MOD_JK (thanks Ubuntu)

Step 2) get the necessary jars from tomcat and put them in the glassfish lib.  I initially installed Tomcat 6.0.14 hoping that it would have the necessary jars but it didn't.  So I had to go get the recommended version (5.5.16) Jean-Francois says you only need tomcat-ajp.jar but Amy Roh's says you need 3 (tomcat-ajp, commons-logging and commons-modeler)

Step 3) enable ajp:

$GLASSFISH_HOME/bin/asadmin create-jvm-options -Dcom.sun.enterprise.web.connector.enableJK=8009

Also you need to define where the properties file is :

$GLASSFISH_HOME/bin/asadmin create-jvm-options -Dcom.sun.enterprise.web.connector.enableJK.propertyFile = <fileName>

That is it sort of... There are a couple of gotcha's on the way, but nothing that is too terribly difficult.  I have to take a lot of things on faith and they usually work but when they don't things get ugly quickly.  The mod_jk needs to be configured in your httpd.conf, also there is a file that defines worker's and what they do, and the enabled MODS (taken care of on step one). 

Ubuntu/Apache does have a very fancy set of commands called a2enmod and a2ensite.  If you're wanting to create a virtual host you setup an virtual host file in the site-available directory and call a2ensite on it - a2enmod works about the same... read here if you're interested about it.


Next I think I'll talk about getting websvn and hgweb setup both are pretty cool.  WebSvn has far more features but Mercurial is pretty dang fancy too though...

Talk to ya later.



Saturday, February 02, 2008


One of my biggest concerns that I had lost was my source code repository.  Again, not a lot of stuff out there but several projects that were kind of interesting.  The good thing about the way my old server crashed was that the hard drive was intact.  I did a very small amount of research and ran across this article basically you issue a command to dump the old repository and issue another command to import it into a new repository.


svnadmin dump /path/to/repo > reponame.dump
tar zcf reponame.tgz reponame.dump
scp reponame.tgz hostname:/path/to/new/repo



cd /path/to/new
svnadmin create reponame
tar zxf reponame.tgz
svnadmin load reponame < reponame.dump


That was basically the extent of recovering my source code repository.




Recovery In Progress

I had been hosting my own domain for awhile not much out there really, more of a sand box for me to work in than anything else.  Somewhere around January 5th the computer I was using as server died.  It wouldn't boot or even POST.  I'm still not sure exactly what happened to it.  I attempted to replace the mother board and CPU but do to a serious lack of inclination and knowledge I never got it working and took all the pieces back to where I purchased them. 

I was feeling all bummed about it, worried I had lost a lot of info (source code, database info, etc.). 

And Just the other day I went out to Nebraska Furniture Mart and found a really good deal on a new Desktop PC.  I went ahead and picked it up and have been going through all the recovery issues that I can.  I'm going to try and document the recovery process and setup of this new server in case it happens again....