Help

I'm pleased to announce the availability of Seam Security 3.0.0 Alpha1. This release is a major rework of the security features from Seam 2.x, so I apologise in advance for the epic release notes. First the important stuff:

Distribution download:

https://sourceforge.net/projects/jboss/files/Seam/Security/3.0.0.Alpha1/seam-security-3.0.0.Alpha1.zip/download

Maven dependency:

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-impl</artifactId>
   <version>3.0.0.Alpha1</version>
</dependency>

Alternatively, you can use the API at compile time and only include the implementation at runtime.

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-api</artifactId>
   <version>3.0.0.Alpha1</version>
   <scope>compile</scope>
</dependency>

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-impl</artifactId>
   <version>3.0.0.Alpha1</version>
   <scope>runtime</scope>
</dependency>

Note: You must configure the JBoss Community Repository in your settings.xml or project POM.

JIRA:

http://jira.jboss.org/jira/browse/SEAMSECURITY

I need to stress that this is an alpha release, and as such some features might be missing or incomplete, and there are sure to be some bugs. I'd like to invite everyone to make ample use of JIRA to report anything and everything that you find out of place or missing, this will greatly help us to prepare for the subsequent releases.

With that out of the way, it's time to buckle up and see what's changed.

Split between API and Implementation

Like many of the other Seam 3 modules, we have split the security module into API and IMPL sub-modules. This was a much requested feature for Seam Security to allow for alternate implementations to be used within unit tests, etc. Core components such as Identity, Credentials and others are now based on interfaces.

Basic Authentication

Authentication via a simple authentication method ala Seam 2 is quite similar in principle. Instead of having to configure an authenticator method in components.xml (which doesn't exist any more), you simply need to provide an implementation of the org.jboss.seam.security.Authenticator interface in your application. When calling Identity.login(), the security module will search for a bean implementing the Authenticator interface and if found use it to perform authentication. This interface declares a single method, authenticate():

public interface Authenticator
{
   boolean authenticate();
}

Implementations may perform whatever logic necessary to authenticate the user, whether that be querying a database or reading user account info from a file. Credentials (containing the user's username and password) may be obtained by injecting the org.jboss.seam.security.Credentials bean directly into your Authenticator.

public class SimpleAuthenticator
{
   @Inject Credentials credentials;
   
   public boolean authenticate()
   {
      // authentication logic here
      
      return true; // if authentication successful
   }
}

One of the major changes in Seam Security is integration with PicketLink. Early on in the planning phase for Seam 3 we decided to look at ways we could unify our security efforts with the JBoss Security team. Seam already had identity management features, however it did not make sense to continue developing these features in parallel (and therefore competing) with the PicketLink IDM project, which had similar goals. With that in mind, we decided to drop the identity management features from Seam and adopt PicketLink IDM as our identity management provider.

PicketLink provides identity store implementations for storing identity-related information using either Hibernate or LDAP, however lacks a JPA implementation. Seam 3 bridges this gap by providing a JPA implementation called JpaIdentityStore, which was inspired by the JpaIdentityStore implementation in Seam 2. This is a total rewrite, and offers much more configuration flexibility when it comes to integrating with legacy db schemas which contain identity-related data. This identity store implementation may eventually make its way into the PicketLink project's code base.

To use JpaIdentityStore to provide identity management features for your own project, you need to configure it in your beans.xml (or seam-beans.xml) file (Seam-XML module is required). First you need to configure a namespace within the root element:

   xmlns:plidm="urn:java:org.jboss.seam.security.management.picketlink"

Then you need to configure the entity classes which contain things such as your user accounts, credentials, roles, and relationships:

   <plidm:JpaIdentityStoreConfiguration>
      <s:replaces/>
      <plidm:identityClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObject</plidm:identityClass>
      <plidm:credentialClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectCredential</plidm:credentialClass>
      <plidm:relationshipClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectRelationship</plidm:relationshipClass>
      <plidm:roleTypeClass>org.jboss.seam.security.examples.idmconsole.model.IdentityRoleName</plidm:roleTypeClass>
   </plidm:JpaIdentityStoreConfiguration>

The above example is from the idmconsole demo application that is included within the Seam Security distribution. It is a simple but concise example that demonstrates how you might build an interface for managing users, roles and groups within your application.

Another important change to note is that the IdentityManager component is no longer part of Seam 3. Replacing it is a set of action beans, found in the org.jboss.seam.security.management.action package. These beans are designed to be used directly by the view layer (such as, but not limited to, JSF) to simplify the interaction between your application and the PicketLink IDM management API. If you want direct access to the API yourself, you can directly inject org.picketlink.idm.api.IdentitySession into your bean:

@Inject IdentitySession identitySession;

From the IdentitySession you can gain access to the PersistenceManager, RelationshipManager, RoleManager, etc for fine-grained control over all aspects of the identity management API. For more information, you can refer to the PicketLink documentation here:

http://anonsvn.jboss.org/repos/picketlink/idm/downloads/docs/1.0.0.GA/ReferenceGuide/en-US/html_single/index.html

API Changes, JAAS deprecation

With the move to PicketLink we have also adopted their Identity API, making use of the base PicketLink classes for User, Role and Group. As a result, we are no longer using the JAAS API within the Identity bean, and the original authentication mechanism (also based on JAAS) has been removed too. This has given us the advantage of first class support for Groups (previously in Seam 2.x, the concept of a group was to allow a grouping of roles). In Seam 3, a role is now a typed mapping between a user and a group. For example, "bob" (a user) may be a "manager" (role type) in "head office" (a group). This gives us more fine-grained control over privileges for groups of users.

Rule-based permissions

There have been a few minor changes to rule-based permissions in Seam 3. First of all, it's no longer required that you configure the rule file, as long as it's named security.drl and located in one of the standard locations for resources according to the Weld Extensions resource loader. Secondly, instead of asserting the Principal obtained from the Identity bean into the working memory, it now asserts a User object, and injects each of the Role and Group memberships assigned to the current user. As a result, you will need to modify the imports for your security rules file, here's an example:

import org.jboss.seam.security.permission.PermissionCheck;
import org.picketlink.idm.api.Role;
import org.picketlink.idm.api.Group;

Role checks performed in rules are slightly different also. Here's an example from the idmconsole demo:

rule CreateAccount
  no-loop
  activation-group "permissions"
when
  check: PermissionCheck(resource == "seam.account", permission == "create", granted == false)
  Role(roleType.name == "admin")
then
  check.grant();
end

Programmatic authorization

We have removed the @Restrict annotation from Seam 3, as this EL-based security mechanism didn't offer the kind of type safety that is encouraged by the CDI programming model. At this stage we don't have a typesafe annnotation-based replacement, however we may introduce one before the final release. For now, authorization can be performed programmatically by injecting the Identity bean into your application bean:

@Inject Identity identity;

Role checks can then be performed like this:

identity.checkRole("superuser", "Head Office", "GROUP");

If the user doesn't possess the required role, an AuthorizationException will be thrown. Simple group membership checks can be performed in a similar way:

identity.checkGroup("Head Office", "GROUP");

Permission checks are very similar to how they were in Seam 2.x, with a slight change in terminology. To align with PicketLink, we've renamed target to resource, and action to permission. The API for checking user permissions now looks like this:

void checkPermission(Object resource, String permission);

Once again, the resource parameter is used to specify the object upon which you wish to test if the current user has the necessary privileges to interact with, and the permission parameter is the name of the specific action that the user wishes to invoke on the resource. So for example, let's say we have an Account object which the current user wishes to delete. To check whether they have the necessary privileges to do this, we perform a permission check like so:

identity.checkPermission(account, "delete");

So what's next?

Here's a list of the things that didn't quite make it into the alpha, but are planned for the final release:

  • External authentication module (due shortly in Alpha2)
  • Persistent permissions (i.e. ACLs)
  • Remember Me
  • Unit Tests
  • Documentation
  • More examples
18 comments:
 
02. Dec 2010, 09:48 CET | Link

All this stuff looks nice. I hope you will add a type safe annotation based API as this is very convenient and increase readability IMO.

I'm a little bit worried though about the cost of porting from seam 2 to seam 3. We are a small team with 2 rather large seam applications now. I hope you're keeping that in mind :)

In this case, we have a lot of already defined permissions, roles, etc. And security is not easy to get right. I hope the migration will be straightforward.

I can't wait the new seam version anyway to try the new jboss, new features, etc :)

ReplyQuote
 
02. Dec 2010, 10:04 CET | Link
simpler programmer

Whats going on with the programming model these days?

Regarding interface Authenticator: Is that a step forward or ten backwards if you no longer prefer to have even parameters with your methods; why is everything @Injected? Carrying a variable over in a method call cannot be more expensive than you proxying an interface to a threadlocal or what ever your strategy is to deliver that @Injected value.

What does anyone gain from moving away from method parameters? Isn't stateless code usually simpler to write than stateful, at least when you compose it from small enough chunks/interfaces.

If the example was supposed to demonstrate that in the SimpleAuthenticator case field type can be Credentials or any authenticator specific subtype, that'd still would not explain giving up on method parameters.

public void authenticate(Credentials creds) {
  if (!(creds instanceof MyCredentialsSubClass)) return false;
  MyCredentialsSubClass credentials = (MyCredentialsSubClass)creds;
 
  // ...

}
 
02. Dec 2010, 11:34 CET | Link
Sertaç Anadollu

I've been waiting for this module for a long time. Many Thanks Shane

 
03. Dec 2010, 00:46 CET | Link
simpler programmer wrote on Dec 02, 2010 04:04:
Regarding interface Authenticator: Is that a step forward or ten backwards if you no longer prefer to have even parameters with your methods; why is everything @Injected? Carrying a variable over in a method call cannot be more expensive than you proxying an interface to a threadlocal or what ever your strategy is to deliver that @Injected value.

The Credentials bean is actually a wrapper interface that among other things exposes a PicketLink Credential instance, the default implementation being a PasswordCredential (the type of credential we're all familiar with). This is beside the point though - whether the Credentials bean is injected into the Authenticator or into the Identity bean (which is where the Authenticator invocation originates from), it's still going to be injected somewhere. The reason it's not declared as a parameter of the authenticate() method is because we don't assume that the credentials will even be required for authentication. Think of the Credentials bean as a convenience which is available for use if you want it, however it's not forced upon you.

I also need to point out that the Authenticator API will most likely change sometime before we release beta 1, as we need to re-architect it slightly to support asynchronous authentication for scenarios like Open ID where the authentication process takes over the request and needs to redirect the user to a 3rd party web site such as Google or Yahoo. We will also most likely be supporting multiple authenticators within a single application where the user can choose which external authentication provider they wish to authenticate with.

 
03. Dec 2010, 23:25 CET | Link

Great job Shane and Marcel. We really needed this!

 
12. Dec 2010, 02:40 CET | Link
scarsick

Is the Seam security model totally bound to the Seam framework or there would be a way to use it in a Java application which doesn't use Seam at all?

 
12. Dec 2010, 16:49 CET | Link
scarsick wrote on Dec 11, 2010 20:40:
Is the Seam security model totally bound to the Seam framework or there would be a way to use it in a Java application which doesn't use Seam at all?

There is no Seam framework as such from Seam 3.0 onwards, Seam is simply a set of portable extensions for Java EE6, security being one of them. When you say Java application what do you mean exactly? A Java SE-based application?

 
12. Dec 2010, 22:52 CET | Link
scarsick

We are planning on building web apps in java using a service-oriented architecture (propably based on RESTful services) where the interface tier will not be coupled in any way with the back-end code. The interface will consist of a single page where components will be generated using JavaScript only and these will communicate with the server by consuming the services. Therefore, we won't be using JSF or any other server-side technology to generate the interface.

We need a powerful security model that supports rule-based authorizations and ACls so we got interested in the Seam security model, but at first glance it looked like if only Seam components (which seems to be JSF components plus...) could be protected. Am I right, or it is possible to protect any class and class instances?

 
13. Dec 2010, 07:54 CET | Link

You describe GWT.

 
13. Dec 2010, 09:01 CET | Link
scarsick wrote on Dec 12, 2010 16:52:
We need a powerful security model that supports rule-based authorizations and ACls so we got interested in the Seam security model, but at first glance it looked like if only Seam components (which seems to be JSF components plus...) could be protected. Am I right, or it is possible to protect any class and class instances?

Seam components (technically they should be referred to as CDI Beans as of Seam 3) may be used in place of JSF components, however they are most certainly not JSF components by definition. From the way you describe your project I can assume that you will be using some kind of servlet-based server-side architecture, such as RESTEasy, in which case Seam Security will work just fine for you, providing both the rule and ACL-based authorization features that you require.

 
13. Dec 2010, 09:12 CET | Link

Actually, I need to correct myself - what we should really be calling these server-side beans are Managed Beans, as they are what the CDI specification builds upon to provide all the goodies such as a contexts, DI, events, etc. JSR-316 is the parent JSR that contains the managed beans specification:

http://jcp.org/aboutJava/communityprocess/final/jsr316/index.html

 
13. Dec 2010, 16:45 CET | Link
scarsick
ГОСТ wrote on Dec 13, 2010 01:54:
You describe GWT.

The end result is very similar, yes... but GWT allows to write Java which will compile to JavaScript, meaning there's still a server-side class that represents your UI widget. In the case I describe, we write JS components in JS directly.

shane wrote on Dec 13, 2010 01:54:
Seam components (technically they should be referred to as CDI Beans as of Seam 3)...

Thanks for your feedback, I will look more into all this but I am glad that what we want to achieve seems feasible with Seam security module. Is there any other Seam modules that I should look into that would be interesting to build the kind of architecture we plan to use?

PS: We always have been a ColdFusion development shop but we are now moving forward to java. We take that opportunity to refactor completely our environment. I don't know much about the available tools yet ;)

 
13. Dec 2010, 17:29 CET | Link
scarsick wrote on Dec 13, 2010 10:45:
ГОСТ wrote on Dec 13, 2010 01:54:
You describe GWT.
The end result is very similar, yes... but GWT allows to write Java which will compile to JavaScript, meaning there's still a server-side class that represents your UI widget. In the case I describe, we write JS components in JS directly.

That is not correct. Java compiles to javascript before deploying to server, so you don’t have UI on server side.

 
14. Dec 2010, 00:59 CET | Link
scarsick wrote on Dec 13, 2010 10:45:
Thanks for your feedback, I will look more into all this but I am glad that what we want to achieve seems feasible with Seam security module. Is there any other Seam modules that I should look into that would be interesting to build the kind of architecture we plan to use?

Hmm, possibly but hard to say without knowing anything about your application. Some of the generally useful modules such as Seam Catch, Persistence and XML config would most likely increase productivity for you. I suggest you take a look at the Seam 3 module list here, that should give you an idea of what is available:

http://www.seamframework.org/Seam3/ProjectStatusAndDirection#H-Modules

 
02. Mar 2011, 14:04 CET | Link
andrey
In Seam 3, a role is now a typed mapping between a user and a group. For example, "bob" (a user) may be a "manager" (role type) in "head office" (a group). This gives us more fine-grained control over privileges for groups of users.

Hi Shane! Can you, please, give some real-life example of using both roles and groups. For example: if I have two users marry and tom who are managers and so they attached to role manager which gives them possibility to do something that managers do. Why would I want to put them into some group for example head office? I just can't understand the concept.

Thank you!

 
15. Mar 2011, 16:10 CET | Link
Manju
Hi, I am in the process of upgrading Seam 2.2.1 to Seam 3.0.0.

I have the permissions check on my services layer as:

if (org.jboss.seam.contexts.Contexts.isSessionContextActive()) {
  return org.jboss.seam.security.Identity.instance().hasPermission(securityName, action.toString());
} else {
  return true;
}

The check is to run the Integration tests when there is no SessionContext (no web context). Can you explain me how to migrate this to Seam 3.0.0?
 
12. Sep 2011, 01:29 CET | Link
M M Islam Chisty | mchisty(AT)gmail.com
A simple question. Please consider the following scenario:

- OSR is a government organization where there are 50 roles (e.g. Manager, Operations manager, Director, Secured developer, Chief operator, Systems director, ..... etc etc etc etc etc). A web based application is developed for OSR using Seam2.2, richfaces/JSF, JBoss5.1.

- In this web application, consider a XHTML page which had 2 buttons ("Save" and "Delete"). The "Save" button will be viewable (rendered="true") to 25 roles and the "Delete" button will visible to another 25 roles. In Seam2 (with Richfaces), one way to accomplish it is like this:


<a4j:commandButton value="Save" rendered="#{s:hasRole('manager')
          or s:hasRole('director')
          or s:hasRole('systemdirector')
          or s:hasRole('securedeveloper')
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          or .......
          }"/> <!-- Do this for 25 different roles; 25 times conditional checking -->
           Similarly, for the "Delete" button, we do this conditional check for rendering for another 25 roles and for 25 times. In case of 100s of pages with different role based conditions for different UI components (buttons, hyperlinks, textfields, checkboxes, texareas, radio buttons), this will be a complete mess. Can you see the problem? Is this a good programming practice?


My question is: is there a bteer way to do this? JBoss drools/rules does not seem to help much in this case. Does seam3 had some better option to provide in such cases?


Thanks,
... Chisty
                                
 
14. Sep 2011, 14:31 CET | Link
ntsankov

You can check for the concrete permission instead of roles. As I understand, you have 25 roles that have the permission somebean:save and 25 have the permission somebean:delete. You can use Drools to assign permissions to each role, check the examples in the documentation about that. This way your expressions will be simply:

rendered="s:hasPersmission('some_bean', 'save', null)"

Post Comment