Posted by Joseph Nusairat
Wed, 16 Jul 2008 04:00:00 GMT
One characteristics of modern web frameworks is to provide lots of functionality out of the box. This functionality ranges from authentication, to batch processing, to validation. For those of you who haven't used Seam's authentication framework; rest assured it is extremely easy to use. However, if you want to add some custom messaging things get a little more complex. I will show you a work around for the custom messaging issue but first let's discuss how to deal wih Seam authentication in general.
The main component to remember is the Identity class. This class stores the user, password, and provides the methods for login in and out. This class is provided by Seam out of the box. In the first part we will create the login itself.
The login can be fairly simple and will use the Identity object. Here is a simple login form.
Partial of login.xhtml
<h:form id="login">
<h:inputText id="username" size="20" value="#{identity.username}" required="true"/>
<h:inputSecret id="password" size="22" value="#{identity.password}" required="true"/>
<h:selectBooleanCheckbox id="rememberMe" value="#{identity.rememberMe}"/>
<h:commandButton value="Login" action="#{identity.login}"/>
In your components.xml we need to tell Seam what class/method to use for authentication by defining an authentication method and class to call when #{identity.login} is called.
components.xml
<security:identity
authenticate-method="#{authenticator.authenticate}"/>
Then you define a Seam component named "authenticator" that provides an "authenticate" method. By default Seam allows you to inject the Identity object (a Seam Session scoped component). A base skeleton of this code is here:
Authenticator.java
@Name("authenticator")
public class Authenticator {
@In
Identity identity;
public boolean authenticate() {
// Do your database, ldap, etc lookup
// then return true/false based on if it was successful
}
}
It's that simple however, there is one IMPORTANT thing to remember when using Seam Security. And that is Authentication != Login. This distinction will for the most part not affect you unless you want to start dealing with error messages.
By default there are two messages, a failure or successful login that are displayed by Seam automatically when an authentication passes/fails. Both of these are defined in the message.resources file as :
message_en.properties
org.jboss.seam.loginFailed=Login failed!
org.jboss.seam.loginSuccessful=Welcome
You can change the messages there. However, what if your requirements are more complex? What if you want to display a message that specifically informs that the username or password is incorrect, or if you are using something like LDAP, and you want to report that their servers are down. Simple enough right? Just do a FacesMessage context look up and add to it? Right? Wrong! What's the problem with this? You run a good chance that the error message will show up twice on the screen. While this isn't the worse thing to happen, it is a bit annoying. So why does this happen? The authenticator provides just that; "authentication" and is not actually performing the login logic. Meaning that the authenticator is actually called multiple times depending on the scenario and you do not necessarily have control over when and how often the authenticator is called.
To fix that we start by not write messages directly inside the authenticator. Instead, we will write login messages where they should be written, at login. So how do we do this while still using Seam's login? One way is to use a combination of the Seam Events/Observers and to write a "custom login".
The purpose of the Events/Observer, is actually quite interesting. You can write an event in one area of the code, and the Observer can pick it up based on a keyword in a separate class and process it. So in the authenticator you can add this line of code whenever you want to raise a specific message.
Events.instance().raiseEvent("invalidLogin", "Invalid password!!");
The first part of the method contains the key "invalidLogin", the second part displays whatever string we want to display to the front end. Please note, the actual method takes an array of Objects for it's second parameter, so you could pass as many strings, or whatever objects you want.
We have now saved this event, now comes the part of retrieving it and storing it to the FacesMessages, this part is a BIT trickier. We need to create our own Identity class. The Identity, as I explained is the component that actually performs the logging in. But wait just earlier i said that Identity is a Seam level component. What we are going to do is basically extend the Identity class and then replace the component with ours. Lets take a look at our custom identity component.
CustomIdentity.java
@Name("org.jboss.seam.security.identity")
@Scope(ScopeType.SESSION)
@Install(precedence = Install.APPLICATION)
@BypassInterceptors
@Startup
public class CustomIdentity extends Identity {
private static final long serialVersionUID = -9154737979944336061L;
@Override
public String login() {
String retVal = "";
try {
// clear out the login message in case it was triggered
// by an authenticate occurring outside the login
loginErrorMessage = null;
retVal = super.login();
} finally {
// check if any error messages were registered from
// this logging., if they are write them out
if (StringUtils.isNotBlank(loginErrorMessage)) {
FacesMessages.instance().add(loginErrorMessage);
}
}
return retVal;
}
private String loginErrorMessage;
/**
* This is used to save off an error message in case of a login.
* @param message
*/
@Observer("invalidLogin")
public void writeInvalidLogin(String message) {
loginErrorMessage = message;
}
}
This code is a bit of a mouthful, but really not that hard to implement. The class level annotations are similar to the ones by default with Identity except we change the precedence to a later time. By default Identity has a BUILT_IN precedence. By changing it to APPLICATION we guarantee that our custom component will be the one used by Seam instead of Seam's own Identity component.
The last method in the code defines the Observer which is called when the event is raised, we are going to set it to a class level string.
Finally in the login method we are going to call the parent's login method (which is Seam's Identity login method) but after the login call we will check to see if any messages were saved by our Events/Observer pattern and if they are we will add them to the FacesMessages.
With those changes in place you will now be able to display login errors without showing them displaying multiple times on a page.
Posted in Java, JavaEE, Seam, JBoss | Tags Seam | no comments | no trackbacks
Posted by Joseph Nusairat
Thu, 20 Dec 2007 16:20:00 GMT
The long awaited news of Java 6 on Leopard has finally been announced, albeit with little fan fare.
Java 6 on Leopard
Apple has released the preview version; meaning a final version should be coming soon. While I find this to be great news for those of us who do Java development on the Mac, I find it intriguing by the fact that it makes special use of 64-bit architecture. However, it's that last part that worries me a bit. Apparently you HAVE to have a Core 2 Duo to use Java 6. So that means myself and two of my business partners Mac laptops will not be able to run Java 6. Now generally developers like to stay on the cutting edge at all times. But really, the Core duos are ONLY a year and a half old? That is NOT that old to have to upgrade.
I guess we shall have to see how desperate the Java developers who use the Mac are. There was a slight alternative right now as well. Someone has ported the unix JDK6 to the Mac with almost complete functionality. (the URL of the site escapes me right now but I will post it when I find it)
Posted in Java, Mac | no comments | no trackbacks
Posted by Joseph Nusairat
Mon, 10 Dec 2007 19:20:00 GMT
Every year brings with it new technologies, this year is of course is no different. One of the biggest changes I have seen this year (which did not really hit ‘till the end of the year) are some of the dynamic language features in Java, specifically Groovy.
Groovy has come a long way and with the 1.5 release over the weekend brings new meta-programming capabilities and better support for DSLs. All of this is supposed to help the Grails framework. And if you have used both you will really see the Ruby influence mixed with Java standards (there are of course many additions since this is a 1.5 release -from 1.0-.
The real power I see is with Groovy's being supported 100% in Grails (of course) and even in JBoss Seam. Besides Seam just being a good tool to bridge the gap between JSF and EJB3 it has quite a bit of support for ease of development when doing jBPM (JBoss' business process management system which can use Drools as part of its decision making process).
I think next year will be interesting to see if (now that the Java dynamic languages have reached good maturity) whether Groovy will really start to grow in the Java community. The NoFluffJustStuff tour has even branched off with a G2 (Groovy and Grails) tour as well.
At any rate, whether you are a Java, Ruby, or Python developer ... the exponential spread in popularity over the last 2 - 3 years of using dynamic languages via DSLs is great for the community. Let's see what 2008 brings.
Posted in Java, Seam, Groovy | Tags Dynamic, Groovy, Java, Seam | no comments | no trackbacks
Posted by Joseph Nusairat
Tue, 20 Feb 2007 05:00:00 GMT

A few days ago, I blogged complaining how in Seam 1.1.5 in order to create your authentication class you had to create a method with 3 parameters: username, password, and a mutable set of roles. Well, this weekend I downloaded Seam 1.1.6 and much to my surprise they've changed it. In 1.1.6 you inject an Identity object into your POJO instead. This identity object contains the username, password, and set of roles. I'd like to think my blog had something to do with that, but I highly doubt it ;-) I just wanted to add this correction and send a kudos to the Seam team for changing it. Of course your authenticate method still has to return a boolean ... but that is much more acceptable behaviour.
Posted in Java, Seam, JBoss | Tags Seam, Security | no comments | no trackbacks
Posted by Joseph Nusairat
Mon, 05 Feb 2007 05:00:00 GMT

I've recently downloaded the latest Seam distribution (1.1.5). 1.1.5 is when Seam adds Security, and I wanted to update the source code for my book, Beginning JBoss Seam, accordingly.
For the most part I’ve been happy with their security implementation; however, there is one thing that really bugged me. In previous “development” releases they had the security class extend an interface. However, that went against the Seam paradigm of using POJOs everywhere. So now they made the security is implemented as a POJO. Now that in itself isn’t bad, but in my opinion their implementation is questionable.
The way Seam implemented it is there is a specific class for login in and out, passing in username and passwords etc. In order to authenticate using it, you are required to create a POJO has a method like boolean (String username, String password, Set roles)
You can name it anything you want. But the parameter and return has to be in that format. Furthermore the method takes in a username and password, and then sets the roles that are assigned to it. So now you are forcing the parameter “roles” to be a mutable object, something I try to avoid at all costs.
Fair enough they had a hard time implementing a solution. But if you are going to the extent to make the method EXTREMELY specific go ahead and just have it implement an interface. Thats what they are there for. A POJO while a great concept, is not a 100% solution. And in general POJOs are great for business services or presentation tier services that could be accessed in a non-specific manner. An authentication mechanism is not that way. Authentications almost always are very specific. you have a username, password and then are going to return authentication credentials. I understand what they were trying to accomplish but sometimes I think people are soo desperate to make everything a POJO, even items that shouldn’t be.
Final thought, I started this blog "Abusing POJOs?" with a question mark, the reason being to ask yourself is this really abuse or is this the way it should be.
Posted in Java, Seam, JBoss | Tags Seam, Security | no comments | no trackbacks
Posted by Brian Sam-Bodden
Fri, 19 Jan 2007 05:00:00 GMT
The Codemash conference got up to a great start. Rarely do you see a first year conference being this well organized. Overall very little hiccups and a great experience. Along the lines of the NoFluffJustStuff tour and at an unbeatable price of just $99, Codemash delivers!
Today Joseph Nusairat from Integrallis delivered his EJB3 - What's new? session and I did my session on Chris Nelson' promising Trails framework. People seemed to enjoy the presentation and I did a bit of live coding. Not enough to screw up on stage but enough to get the Wow factor going.
As a Rails convert is fun to try to emulate the things that I'm able to accomplish with Rails in frameworks like Trails and Grails. It is interesting to compare and contrast development styles, even on a single individual (me) as I move from Ruby to Java and back to Ruby. Trails definitively has a great future as one of Java's new breed of meta-frameworks. The project website definitively needs some work and some documentation needs to be refined and some created to drive more traffic to the project. Overall, one of the things that's sold me to Trails is its usage of Maven2. Maven2 definitively makes building and managing dependencies in a Java application a breeze.
After my session I got to attend Ted Neward's Java/.Net interop and was promptly used by Ted as a presentation prop. Ted's style of presenting is entertaining yet it drives the point home. Ted's whole point is that 80 some percent of shops are either Java or .Net and the bigger the shop the more likely is that you'll have both and that they will need to share something or talk to each other. Ted outlined the two stacks and the places where they can interoperate, from sharing the DB, to Web Services with REST or SOAP. Also, he touched on some of the areas I've been working/playing with such as integration of Windows native applications with Eclipse RCP. Interesting stuff. The one thing that as an aspiring product development company we were reminded of by Ted's talk, is that Office, like it or not is still the desktop killer app and riding on it's entrenchment on the desktop is an effectively vehicle for your product to reach a large audience.
Posted in Java, Ruby, Rails | Tags Codemash | no comments | no trackbacks