Seam security also makes it possible to apply security restrictions to read, insert, update and delete actions for entities.
To secure all actions for an entity class, add a @Restrict
annotation on the class itself:
@Entity
@Name("customer")
@Restrict
public class Customer {
...
}
If no expression is specified in the @Restrict
annotation, the default security check that is performed is a permission check of entityName:action
, where entityName
is the Seam component name of the entity (or the fully-qualified class name if no @Name is specified), and the action
is either read
, insert
, update
or delete
.
It is also possible to only restrict certain actions, by placing a @Restrict
annotation on the relevent entity lifecycle method (annotated as follows):
-
@PostLoad
- Called after an entity instance is loaded from the database. Use this method to configure a read
permission.
-
@PrePersist
- Called before a new instance of the entity is inserted. Use this method to configure an insert
permission.
-
@PreUpdate
- Called before an entity is updated. Use this method to configure an update
permission.
-
@PreRemove
- Called before an entity is deleted. Use this method to configure a delete
permission.
Here's an example of how an entity would be configured to perform a security check for any insert
operations. Please note that the method is not required to do anything, the only important thing in regard to security is how it is annotated:
@PrePersist @Restrict
public void prePersist() {}
And here's an example of an entity permission rule that checks if the authenticated user is allowed to insert a new MemberBlog
record (from the seamspace example). The entity for which the security check is being made is automatically asserted into the working memory (in this case MemberBlog
):
rule InsertMemberBlog
no-loop
activation-group "permissions"
when
check: PermissionCheck(name == "memberBlog", action == "insert", granted == false)
Principal(principalName : name)
MemberBlog(member : member -> (member.getUsername().equals(principalName)))
then
check.grant();
end;
This rule will grant the permission memberBlog:insert
if the currently authenticated user (indicated by the Principal
fact) has the same name as the member for which the blog entry is being created. The "name : name
" structure that can be seen in the Principal
fact (and other places) is a variable binding - it binds the name
property of the Principal
to a variable called name
. Variable bindings allow the value to be referred to in other places, such as the following line which compares the member's username to the Principal
name. For more details, please refer to the JBoss Rules documentation.
Finally, we need to install a listener class that integrates Seam security with your JPA provider.
Security checks for EJB3 entity beans are performed with an EntityListener
. You can install this listener by using the following META-INF/orm.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="https://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/persistence/orm
https://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="org.jboss.seam.security.EntitySecurityListener"/>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>