Thursday, May 14, 2009

Implementing Application Security with SEAM

Seam helps you secure your application without spending too much time in the details. Seam’s security model is based on a role based system. Seam leverages the Drools rule engine to support contextual, role-based permissions. The fact that we don’t have to write a single line of XML is very welcoming to developers who have used other java security framework.
Authentication:
The authentication features are built upon JAAS, but Seam offers simplified methods of authentication that hides the complexity of JAAS.
Steps for implementing authentication:
1. Switch authentication through Configuration:
You have to tell Seam which method handles the authentication logic. The authentication method ->
  • Must take no argument.
  • Must return a Boolean indicating if credential could be verified.
  • Must be accessible via the EL.

The authentication method can have any name and can reside in any class. The authentication routine is activated through Seam’s Identity component. You can bind the authenticating method to Identity component by adding the following line in components.xml

The above line means the authenticate method in the authenticator component will be used for authentication.
2. Write an authentication method to verify user credential

@Name("authenticator")
public class Authenticator {
@In Identity identity;
@In
private EntityManager entityManager;
public boolean authenticate() {
String username = identity.getUsername();
String PASSWORD = identity. getPassword ();
try {
User user = (User)entityManager.createQuery("select u from User u where u.username like :username and u.password like :password ")
.setParameter("username", username)
.setParameter("password ", password)
.getSingleResult();
if(null != user.getRoles()){
for(Role role: user.getRoles(){
identity.addRole(role.getName());} }
} catch (NoResultException ex) {
log.error("Invalid username/password.", ex);
return false;}
return true;
}

In the above example both User and Role are application specific entity beans. The username and password in the identity component are used to find a matching User entity in DB through entityManager. Once the user is validated, the roles assigned to the user are added to the identity component.

3. Create a login form.
The login form boils down to binding the username and password properties from the identity component to the username and password fields on the login form. After the properties are set, the login method in identity component is called to authenticate the user.
Below is an example of simple login form->

<div> <h:outputLabel for="username">Username</ h:outputLabel> <h:inputText id=" username value="#{identity.username}"/> </div>
<div> <h:outputLabel for="password">Password</ h:outputLabel> <h:inputSecret id="password" value="#{identity.password}"/> </div>
<div> <h:commandButton value="Login" action="#{identity.login}"/> </div>

Authorization:
Authorization is about checking if a user is permitted to access a restricted resource or permitted to perform a restricted action.
Role based authorization:
Seam component are secured either in the class level or method level with @Restrict annotation.
Class Level Restriction:
Example: Restrict the component to only users with Admin role

@Restrict(“#{s:hasRole(‘admin’)}”)
Public class AdminAction{
Public void add(){
}
Public void delete(){
}
}

In the above example the user need to have admin role to perform any action under AdminAction class.

Method Level Restriction:
Example: Only Super user can “delete” and Admin user can “add”.

@Restrict(“#{s:hasRole(‘admin’)}”)
Public class AddDeleteAction{
@Restrict(“#{s:hasRole(‘admin)}”)
Public void add(){
}
@Restrict(“#{s:hasRole(‘super)}”)
Public void delete(){
}
}

In the above example the user need to have admin role to perform “add” operation and super user access to perform “delete” operation.

Note: If “Restrict” is applied both at class level and method level, method level restriction takes precedence.

Rule based Authorization
Seam uses JBoss Rules to provide rule bases authorization. The advantage of rule bases authorization is a centralized location for business logics and user permissions.

Steps for Rule based authorization:
1. Configure RuleBase Component in components.xml.

/META-INF/security-rules.drl


2. Write Security rules file
Create a security-rules.drl in the /META-INF directory of the application’s jar file. The file should look like below->


package RuleCheck;
import org.jboss.seam.security.PermissionCheck;
import org.jboss.seam.security.Role;

rule CanModifyRole
when
c: PermissionCheck(name == "Role", action == "update")
Role(name == "admin")
then
c.grant()
end;

The above rule states that only admin user can modify roles of other User. In the line
c: PermissionCheck(name == "Role", action == "update")
“name==’Role’” specifies the entity/component for which permission is granted and “action=’update’” specifies the specific action the user is granted access to.

3 comments:

  1. Very usefull!! In each day that I study I see the powerfull framework that seam is becoming. I cannot imagine jsf development without seam anymore.

    Thank you

    ReplyDelete
  2. Indeed nice artical can you help me out on this?

    http://seamframework.org/Community/ErrorParsingIdentityhasRoleadmin

    ReplyDelete