15.6.2. Securing components
We will start with the simplest form of authorization: component security. First, we will look at the
@Restrict
annotation.
Note
While the
@Restrict
annotation is a powerful and flexible method for security components, it cannot support EL expressions. Therefore, we recommend using the typesafe equivalent (described later in this chapter) for its compile-time safety.
15.6.2.1. The @Restrict annotation
Seam components can be secured at either the method or the class level with the
@Restrict
annotation. If both a method and its declaring class are annotated with @Restrict
, the method restriction will take precedence and the class restriction will not apply. If a method invocation fails a security check, an exception will be thrown as per the contract for Identity.checkRestriction()
. (See the section following for more information on Inline Restrictions.) Placing @Restrict
on the component class itself is the equivalent of adding @Restrict
to each of its methods.
An empty
@Restrict
implies a permission check of componentName:methodName
. Take for example the following component method:
@Name("account") public class AccountAction { @Restrict public void delete() { ... } }
In this example,
account:delete
is the implied permission required to call the delete()
method. This is equivalent to writing @Restrict("#{s:hasPermission('account','delete')}")
. The following is another example:
@Restrict @Name("account") public class AccountAction { public void insert() { ... } @Restrict("#{s:hasRole('admin')}") public void delete() { ... } }
Here, the component class itself is annotated with
@Restrict
. This means that any methods without an overriding @Restrict
annotation require an implicit permission check. In this case, the insert()
method requires a permission of account:insert
, while the delete()
method requires that the user is a member of the admin
role.
Before we go further, we will address the
#{s:hasRole()}
expression seen in the previous example. s:hasRole
and s:hasPermission
are EL functions that delegate to the correspondingly-named methods of the Identity
class. These functions can be used within any EL expression throughout the entirety of the security API.
Being an EL expression, the value of the
@Restrict
annotation may refer to any object within a Seam context. This is extremely useful when checking permissions for a specific object instance. Take the following example:
@Name("account") public class AccountAction { @In Account selectedAccount; @Restrict("#{s:hasPermission(selectedAccount,'modify')}") public void modify() { selectedAccount.modify(); } }
In this example, the
hasPermission()
function call refers to selectedAccount
. The value of this variable will be looked up from within the Seam context, and passed to the hasPermission()
method in Identity
. This will determine whether the user has the required permissions to modify the specified Account
object.