This particular tip on loading different homepages for the role associated for a specific logged in user for a JSF web application written using JBoss Seam and identity management using Seam-Security. This tip assumes that a single user will be associated with a single role.
Assume we need to develop a course management JSF application which supports users of 2 different roles : teacher and student. This means if a user with teacher role logs in teacher specific homepage should come and student logging in should display student homepage. The following are steps to achieve this requirement.
1) Change WEB-INF/components.xml to include the seam-security authentication patterns
<components xmlns="http://jboss.com/products/seam/components"
....
xmlns:security="http://jboss.com/products/seam/security"
xsi:schemaLocation="http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
....
">
...
<security:identity authenticate-method="#{authenticator.authenticate}"/>
</components>
2) Define an Authenticator action class with JBoss Seam component name “authenticator” and define an authenticate method inside
@Name("authenticator")
public class AuthenticatorAction
{ @In
private Identity identity;
@In(create=true)
private AuthService service;
...
@SuppressWarnings("deprecated")
public boolean authenticate()
{ String username = identity.getUsername();
String password = identity.getPassword();
if(username==null || password==null)
return false;
//authenticate the user from database
User user = service.authenticate(username,password);
// check user validity.
identity.addRole(user.getRole());
return true;
}
}
3) Define the login portal widget in the login-page (say login.xhtml)
<ui:composition xmlns="http://www.w3.org/1999/xhtml">
.....
<h:panelGrid columns="2" style="width:27px">
<h:outputText value="Username: "/>
<h:inputText id="username" value="#{identity.username}" rows="1" cols="12">
<f:validateLength minimum="8" />
</h:inputText>
<h:outputText value="Password:" rows="1" cols="12"/>
<h:inputSecret id="password" value="#{identity.password}" />
</h:panelGrid>
<h:commandButton id="login" action="#{identity.login}" value="Login"/>
...
</ui:composition>
4) Wire the action outcomes to set up the navigation paths in WEB-INF/pages.xml
<pages xmlns="http://jboss.com/products/seam/pages"
....
no-conversation-view-id="/index.html">
<page view-id="/login.xhtml">
<navigation from-action="#{authenticator.checkLogin}">
<rule if="#{identity.loggedIn and identity.role=='Teacher'}">
<redirect view-id="/teacher/homepage.xhtml" />
</rule>
</navigation>
<navigation from-action="#{identity.login}">
<rule if="#{identity.loggedIn and identity.hasRole('Teacher')}">
<redirect view-id="/teacher/homepage.xhtml" />
</rule>
</navigation>
<navigation from-action="#{authenticator.checkLogin}">
<rule if="#{identity.loggedIn and identity.role=='Student'}">
<redirect view-id="/student/homepage.xhtml" />
</rule>
</navigation>
<navigation from-action="#{identity.login}">
<rule if="#{identity.loggedIn and identity.hasRole('Student')}">
<redirect view-id="/student/homepage.xhtml" />
</rule>
</navigation>
</page>
....
<exception>
<redirect view-id="/index.xhtml">
<message>Please log in first</message>
</redirect>
</exception>
</pages>
You can extend this tip to come out of different other user-role combinations.