[seam-commits] Seam SVN: r8396 - trunk/doc/Seam_Reference_Guide/en-US.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Fri Jun 20 00:08:36 EDT 2008
Author: shane.bryzak at jboss.com
Date: 2008-06-20 00:08:36 -0400 (Fri, 20 Jun 2008)
New Revision: 8396
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Security.xml
Log:
work in progress
Modified: trunk/doc/Seam_Reference_Guide/en-US/Security.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Security.xml 2008-06-19 20:14:32 UTC (rev 8395)
+++ trunk/doc/Seam_Reference_Guide/en-US/Security.xml 2008-06-20 04:08:36 UTC (rev 8396)
@@ -3,82 +3,54 @@
<chapter id="security">
<title>Security</title>
- <para>
- The Seam Security API is an optional Seam feature that provides authentication and authorization features
- for securing both domain and page resources within your Seam project.
- </para>
-
<sect1>
<title>Overview</title>
-
+
<para>
- Seam Security provides two different modes of operation:
+ The Seam Security API provides a multitude of security-related features for your Seam-based application, covering
+ such areas as:
</para>
-
+
<itemizedlist>
<listitem>
<para>
- <emphasis>simplified mode</emphasis> - this mode supports authentication services
- and simple role-based security checks.
+ Authentication - an extensible, JAAS-based authentication layer that allows users to authenticate
+ against any security provider.
</para>
</listitem>
<listitem>
<para>
- <emphasis>advanced mode</emphasis> - this mode supports all the same features as the simplified mode,
- plus it offers rule-based security checks using JBoss Rules.
+ Identity Management - an API for managing a Seam application's users and roles at runtime.
</para>
</listitem>
- </itemizedlist>
-
- <sect2>
- <title>Which mode is right for my application?</title>
-
- <para>
- That all depends on the requirements of your application. If you have minimal security requirements, for example
- if you only wish to restrict certain pages and actions to users who are logged in, or who belong to a certain role,
- then the simplified mode will probably be sufficient. The advantages of this is a more simplified configuration,
- significantly less libraries to include, and a smaller memory footprint.
- </para>
-
- <para>
- If on the other hand, your application requires security checks based on contextual state or complex business rules,
- then you will require the features provided by the advanced mode.
- </para>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Requirements</title>
-
- <para>
- If using the advanced mode features of Seam Security, the following jar files are required to be configured as modules in
- <literal>application.xml</literal>. If you are using Seam Security in simplified mode, these are <emphasis>not</emphasis>
- required:
- </para>
-
- <itemizedlist>
<listitem>
- <para>drools-compiler.jar</para>
+ <para>
+ Authorization - an extremely comprehensive authorization framework, supporting user roles, persistent and
+ rule-based permissions, and a pluggable permission resolver for easily implementing customised security logic.
+ </para>
</listitem>
<listitem>
- <para>drools-core.jar</para>
+ <para>
+ Permission Management - a set of built-in Seam components to allow easy management of an application's
+ security policy.
+ </para>
</listitem>
<listitem>
- <para>janino.jar</para>
+ <para>
+ CAPTCHA support - to assist in the prevention of automated software/scripts abusing your Seam-based site.
+ </para>
</listitem>
<listitem>
- <para>antlr-runtime.jar</para>
+ <para>
+ And much more
+ </para>
</listitem>
- <listitem>
- <para>mvel14.jar</para>
- </listitem>
- </itemizedlist>
-
+ </itemizedlist>
+
<para>
- For web-based security, <literal>jboss-seam-ui.jar</literal> must also be included in the application's war file.
- </para>
+ This chapter will cover each of these features in detail.
+ </para>
-
</sect1>
<sect1>
@@ -105,7 +77,7 @@
</listitem>
</itemizedlist>
</sect1>
-
+
<sect1>
<title>Authentication</title>
@@ -114,17 +86,22 @@
and as such provide a robust and highly configurable API for handling user authentication. However, for less complex
authentication requirements Seam offers a much more simplified method of authentication that hides the complexity of JAAS.
</para>
-
+
<sect2>
- <title>Configuration</title>
+ <title>Configuring an Authenticator component</title>
+ <note>
+ If you use Seam's Identity Management features (discussed later in this chapter) then it is not necessary to create
+ an authenticator component (and you can skip this section).
+ </note>
+
<para>
- The simplified authentication method uses a built-in JAAS login module, <literal>SeamLoginModule</literal>, which
+ The simplified authentication method provided by Seam uses a built-in JAAS login module, <literal>SeamLoginModule</literal>, which
delegates authentication to one of your own Seam components. This login module is already configured inside Seam as
part of a default application policy and as such does not require any additional configuration files. It allows you to
- write an authentication method using the entity classes that are provided by your own application. Configuring this
- simplified form of authentication requires the <literal>identity</literal> component to be configured in
- <literal>components.xml</literal>:
+ write an authentication method using the entity classes that are provided by your own application, or alternatively to
+ authenticate against some other third party provider. Configuring this simplified form of authentication requires the
+ <literal>identity</literal> component to be configured in <literal>components.xml</literal>:
</para>
<programlisting role="XML"><![CDATA[<components xmlns="http://jboss.com/products/seam/components"
@@ -140,12 +117,6 @@
</components>]]></programlisting>
<para>
- If you wish to use the advanced security features such as rule-based permission checks, all you need
- to do is include the Drools (JBoss Rules) jars in your classpath, and add some additional configuration,
- described later.
- </para>
-
- <para>
The EL expression <literal>#{authenticator.authenticate}</literal> is a method binding indicating that
the <literal>authenticate</literal> method of the <literal>authenticator</literal> component will be used
to authenticate the user.
@@ -161,29 +132,31 @@
<literal>components.xml</literal> specifies which method will be used by <literal>SeamLoginModule</literal>
to authenticate users. This method takes no parameters, and is expected to return a boolean indicating
whether authentication is successful or not. The user's username and password can be obtained from
- <literal>Identity.instance().getUsername()</literal> and <literal>Identity.instance().getPassword()</literal>,
+ <literal>Credentials.getUsername()</literal> and <literal>Credentials.getPassword()</literal>,
respectively. Any roles that the user is a member of should be assigned using
- <literal>Identity.instance().addRole()</literal>. Here's a complete example of an authentication method
- inside a JavaBean component:
+ <literal>Identity.addRole()</literal>. Here's a complete example of an authentication method
+ inside a POJO component:
</para>
<programlisting role="JAVA"><![CDATA[@Name("authenticator")
public class Authenticator {
@In EntityManager entityManager;
+ @In Credentials credentials;
+ @In Identity identity;
public boolean authenticate() {
try
{
User user = (User) entityManager.createQuery(
"from User where username = :username and password = :password")
- .setParameter("username", Identity.instance().getUsername())
- .setParameter("password", Identity.instance().getPassword())
+ .setParameter("username", credentials.getUsername())
+ .setParameter("password", credentials.getPassword())
.getSingleResult();
if (user.getRoles() != null)
{
for (UserRole mr : user.getRoles())
- Identity.instance().addRole(mr.getName());
+ identity.addRole(mr.getName());
}
return true;
@@ -204,6 +177,16 @@
In this case, if the user record is not found and a <literal>NoResultException</literal> thrown, the
authentication method returns <literal>false</literal> to indicate the authentication failed.
</para>
+
+ <note>
+ When writing an authenticator method, it is important that it is kept minimal and free from
+ any side-effects. This is because there is no guarantee as to how many times the authenticator
+ method will be called by the security API, and as such it may be invoked multiple times during
+ a single request. Because of this, any special code that should execute upon a successful or
+ failed authentication should be written by implementing an event observer. See the section on
+ Security Events further down in this chapter for more information about which events are
+ raised by Seam Security.
+ </note>
<sect3>
<title>Identity.addRole()</title>
@@ -227,24 +210,19 @@
<imagedata fileref="images/security-addrole.png" align="center"/>
</imageobject>
</mediaobject>
+
+ <para>
+ If the current session is already authenticated, then calling <literal>Identity.addRole()</literal> will
+ have the expected effect of immediate granting the current user the specified role.
+ </para>
</sect3>
<sect3>
- <title>Special Considerations</title>
+ <title>Writing an event observers for security-related events</title>
<para>
- When writing an authenticator method, it is important that it is kept minimal and free from
- any side-effects. This is because there is no guarantee as to how many times the authenticator
- method will be called by the security API, and as such it may be invoked multiple times during
- a single request. Because of this, any special code that should execute upon a successful or
- failed authentication should be written by implementing an event observer. See the section on
- Security Events further down in this chapter for more information about which events are
- raised by Seam Security.
- </para>
-
- <para>
- To give an example, let's say that upon a successful login that some user statistics must be
+ Let's say for example that upon a successful login that some user statistics must be
updated. We would do this by writing an event observer for the
<literal>org.jboss.seam.security.loginSuccessful</literal> event, like this:
</para>
@@ -257,6 +235,11 @@
userStats.setLastLoginDate(new Date());
userStats.incrementLoginCount();
}]]></programlisting>
+
+ <para>
+ This observer method can be placed anywhere, even in the Authenticator component itself.
+ You can find more information about security-related events later in this chapter.
+ </para>
</sect3>
</sect2>
@@ -265,21 +248,21 @@
<title>Writing a login form</title>
<para>
- The <literal>Identity</literal> component provides both <literal>username</literal> and <literal>password</literal>
+ The <literal>credentials</literal> component provides both <literal>username</literal> and <literal>password</literal>
properties, catering for the most common authentication scenario. These properties can be bound directly to the
- username and password fields on a login form. Once these properties are set, calling the
- <literal>identity.login()</literal> method will authenticate the user using the provided credentials.
+ username and password fields on a login form. Once these properties are set, calling
+ <literal>identity.login()</literal> will authenticate the user using the provided credentials.
Here's an example of a simple login form:
</para>
<programlisting role="XHTML"><![CDATA[<div>
<h:outputLabel for="name" value="Username"/>
- <h:inputText id="name" value="#{identity.username}"/>
+ <h:inputText id="name" value="#{credentials.username}"/>
</div>
<div>
<h:outputLabel for="password" value="Password"/>
- <h:inputSecret id="password" value="#{identity.password}"/>
+ <h:inputSecret id="password" value="#{credentials.password}"/>
</div>
<div>
@@ -288,13 +271,13 @@
<para>
Similarly, logging out the user is done by calling <literal>#{identity.logout}</literal>. Calling this
- action will clear the security state of the currently authenticated user.
+ action will clear the security state of the currently authenticated user, and invalidate the user's session.
</para>
</sect2>
<sect2>
- <title>Simplified Configuration - Summary</title>
+ <title>Configuration Summary</title>
<para>
So to sum up, there are the three easy steps to configure authentication:
</para>
@@ -509,9 +492,653 @@
itself using the configured JAAS security policy.
</para>
</sect3>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Identity Management</title>
+
+ <para>
+ Identity Management provides a standard API for the management of a Seam application's users and roles,
+ regardless of which identity store (database, LDAP, etc) is used on the backend. At the center
+ of the Identity Management API is the <literal>identityManager</literal> component, which provides
+ all the methods for creating, modifying and deleting users, granting and revoking roles, changing passwords,
+ enabling and disabling user accounts, authenticating users and listing users and roles.
+ </para>
+
+ <sect2>
+ <title>Configuring IdentityManager</title>
+
+ <para>
+ The <literal>identityManager</literal> component allows for separate identity stores to be configured
+ for authentication and authorization operations. This means that it is possible for users to
+ be authenticated against one identity store, for example an LDAP directory, yet have their roles
+ loaded from another identity store, such as a relational database.
+ </para>
+
+ <para>
+ Seam provides two <literal>IdentityStore</literal> implementations out of the box;
+ <literal>JpaIdentityStore</literal> uses a relational database to store user and role information,
+ and is the default identity store that is used if nothing is explicitly configured in the
+ <literal>identityManager</literal> component. The other implementation that is provided is
+ <literal>LdapIdentityStore</literal>, which uses an LDAP directory to store users and roles.
+ </para>
+
+ <para>
+ There are two configurable properties for the <literal>identityManager</literal> component -
+ <literal>identityStore</literal> and <literal>roleIdentityStore</literal>. The value for these
+ properties must be an EL expression referring to a Seam component implementing the
+ <literal>IdentityStore</literal> interface. As already mentioned,
+ if left unconfigured then <literal>JpaIdentityStore</literal> will be assumed by default. If
+ only the <literal>identityStore</literal> property is configured, then the same value will be used for
+ <literal>roleIdentityStore</literal> also. For example, the following entry in
+ <literal>components.xml</literal> will configure <literal>identityManager</literal> to use
+ an <literal>LdapIdentityStore</literal> for both user-related and role-related operations:
+ </para>
+ <programlisting><![CDATA[
+ <security:identity-manager identity-store="#{ldapIdentityStore}"/>
+ ]]></programlisting>
+
+ <para>
+ The following example configures <literal>identityManager</literal> to use an <literal>LdapIdentityStore</literal>
+ for user-related operations, and <literal>JpaIdentityStore</literal> for role-related operations:
+ </para>
+
+ <programlisting><![CDATA[
+ <security:identity-manager
+ identity-store="#{ldapIdentityStore}"
+ role-identity-store="#{jpaIdentityStore}"/>
+ ]]></programlisting>
+
+ <para>
+ The following sections explain both of these identity store implementations in greater detail.
+ </para>
+
</sect2>
+
+ <sect2>
+ <title>JpaIdentityStore</title>
+
+ <para>
+ This identity store allows for users and roles to be stored inside a relational database. It is designed
+ to be as unrestrictive as possible in regards to database schema design, allowing a great deal of
+ flexibility in the underlying table structure. This is achieved through the use of a set of special
+ annotations, allowing entity beans to be configured to store user and role records.
+ </para>
+
+ <sect3>
+ <title>Configuring JpaIdentityStore</title>
+
+ <para>
+ <literal>JpaIdentityStore</literal> requires that both the <literal>user-class</literal> and
+ <literal>role-class</literal> properties are configured. These properties should refer to the
+ entity classes that are to be used to store both user and role records, respectively. The following
+ example shows the configuration from <literal>components.xml</literal> in the SeamSpace example:
+ </para>
+
+ <programlisting><![CDATA[
+ <security:jpa-identity-store
+ user-class="org.jboss.seam.example.seamspace.MemberAccount"
+ role-class="org.jboss.seam.example.seamspace.MemberRole"/>
+ ]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Configuring the Entities</title>
+
+ <para>
+ As already mentioned, a set of special annotations are used to configure entity beans for storing
+ users and roles. The following table lists each of the annotations, and their descriptions.
+ </para>
+
+ <table>
+ <title>User Entity Annotations</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="1*" />
+ <colspec colnum="3" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Annotation</para>
+ </entry>
+ <entry align="center">
+ <para>Status</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>@UserPrincipal</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Required</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the user's username.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@UserPassword</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Required</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the user's password. It allows a <literal>hash</literal>
+ algorithm to be specified for password hashing. Possible values for <literal>hash</literal> are
+ <literal>md5</literal> and <literal>sha</literal>. E.g:
+
+ <programlisting><![CDATA[@UserPassword(hash = "md5")
+public String getPasswordHash() {
+ return passwordHash;
+}]]></programlisting>
+
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@UserFirstName</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Optional</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the user's first name.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@UserLastName</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Optional</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the user's last name.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@UserEnabled</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Optional</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the enabled status of the user. This should be a boolean
+ property, and if not present then all user accounts are assumed to be enabled.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@UserRoles</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Required</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the roles of the user. This property will be described in
+ more detail further down.
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Role Entity Annotations</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="1*" />
+ <colspec colnum="3" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Annotation</para>
+ </entry>
+ <entry align="center">
+ <para>Status</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>@RoleName</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Required</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the name of the role.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@RoleGroups</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Optional</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method containing the group memberships of the role.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>@RoleConditional</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>Optional</para>
+ </entry>
+ <entry>
+ <para>
+ This annotation marks the field or method indicating whether the role is conditional or not.
+ Conditional roles are explained later in this chapter.
+ </para>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect3>
+
+ <sect3>
+ <title>Entity Bean Examples</title>
+
+ <para>
+ As mentioned previously, <literal>JpaIdentityStore</literal> is designed to be as flexible as possible when
+ it comes to the database schema design of your user and role tables. This section looks at a number of
+ possible database schemas that can be used to store user and role records.
+ </para>
+
+ <sect4>
+ <title>Minimal schema example</title>
+
+ <para>
+ In this bare minimal example, a simple user and role table are linked via a
+ many-to-many relationship using a cross-reference table named <literal>UserRoles</literal>.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/security-entities-1.png" align="center" scalefit="1"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/security-entities-1.png" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <programlisting><![CDATA[@Entity
+public class User {
+ private Integer userId;
+ private String username;
+ private String passwordHash;
+ private Set<Role> roles;
+
+ @Id @GeneratedValue
+ public Integer getUserId() { return userId; }
+ public void setUserId(Integer userId) { this.userId = userId; }
+
+ @UserPrincipal
+ public String getUsername() { return username; }
+ public void setUsername(String username) { this.username = username; }
+
+ @UserPassword(hash = "md5")
+ public String getPasswordHash() { return passwordHash; }
+ public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
+
+ @UserRoles
+ @ManyToMany(targetEntity = Role.class)
+ @JoinTable(name = "UserRoles",
+ joinColumns = @JoinColumn(name = "UserId"),
+ inverseJoinColumns = @JoinColumn(name = "RoleId"))
+ public Set<Role> getRoles() { return roles; }
+ public void setRoles(Set<Role> roles) { this.roles = roles; }
+}]]></programlisting>
+<programlisting><![CDATA[@Entity
+public class Role {
+ private Integer roleId;
+ private String rolename;
+
+ @Id @Generated
+ public Integer getRoleId() { return roleId; }
+ public void setRoleId(Integer roleId) { this.roleId = roleId; }
+
+ @RoleName
+ public String getRolename() { return rolename; }
+ public void setRolename(String rolename) { this.rolename = rolename; }
+}]]></programlisting>
+ </sect4>
+
+ <sect4>
+ <title>Complex Schema Example</title>
+
+ <para>
+ This example builds on the above minimal example by including all of the optional fields, and allowing
+ group memberships for roles.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/security-entities-2.png" align="center" scalefit="1"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/security-entities-2.png" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <programlisting><![CDATA[@Entity
+public class User {
+ private Integer userId;
+ private String username;
+ private String passwordHash;
+ private Set<Role> roles;
+ private String firstname;
+ private String lastname;
+ private boolean enabled;
+
+ @Id @GeneratedValue
+ public Integer getUserId() { return userId; }
+ public void setUserId(Integer userId) { this.userId = userId; }
+
+ @UserPrincipal
+ public String getUsername() { return username; }
+ public void setUsername(String username) { this.username = username; }
+
+ @UserPassword(hash = "md5")
+ public String getPasswordHash() { return passwordHash; }
+ public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
+
+ @UserFirstName
+ public String getFirstname() { return firstname; }
+ public void setFirstname(String firstname) { this.firstname = firstname; }
+
+ @UserLastName
+ public String getLastname() { return lastname; }
+ public void setLastname(String lastname) { this.lastname = lastname; }
+
+ @UserEnabled
+ public boolean isEnabled() { return enabled; }
+ public void setEnabled(boolean enabled) { this.enabled = enabled; }
+
+ @UserRoles
+ @ManyToMany(targetEntity = Role.class)
+ @JoinTable(name = "UserRoles",
+ joinColumns = @JoinColumn(name = "UserId"),
+ inverseJoinColumns = @JoinColumn(name = "RoleId"))
+ public Set<Role> getRoles() { return roles; }
+ public void setRoles(Set<Role> roles) { this.roles = roles; }
+}]]></programlisting>
+<programlisting><![CDATA[@Entity
+public class Role {
+ private Integer roleId;
+ private String rolename;
+ private boolean conditional;
+
+ @Id @Generated
+ public Integer getRoleId() { return roleId; }
+ public void setRoleId(Integer roleId) { this.roleId = roleId; }
+
+ @RoleName
+ public String getRolename() { return rolename; }
+ public void setRolename(String rolename) { this.rolename = rolename; }
+
+ @RoleConditional
+ public boolean isConditional() { return conditional; }
+ public void setConditional(boolean conditional) { this.conditional = conditional; }
+
+ @RoleGroups
+ @ManyToMany(targetEntity = Role.class)
+ @JoinTable(name = "RoleGroups",
+ joinColumns = @JoinColumn(name = "RoleId"),
+ inverseJoinColumns = @JoinColumn(name = "GroupId"))
+ public Set<Role> getGroups() { return groups; }
+ public void setGroups(Set<Role> groups) { this.groups = groups; }
+
+}]]></programlisting>
+ </sect4>
+
+ </sect3>
+
+ <sect3>
+ <title>JpaIdentityStore Events</title>
+
+ <para>
+ When using <literal>JpaIdentityStore</literal> as the identity store implementation with <literal>IdentityManager</literal>,
+ a few events are raised as a result of invoking certain <literal>IdentityManager</literal> methods.
+ </para>
+
+ <sect4>
+ <title>JpaIdentityStore.EVENT_PRE_PERSIST_USER</title>
+
+ <para>
+ This event is raised in response to calling <literal>IdentityManager.createUser()</literal>. Just before the user
+ entity is persisted to the database, this event will be raised passing the entity instance as an event parameter.
+ The entity will be an instance of the <literal>user-class</literal> configured for <literal>JpaIdentityStore</literal>.
+ </para>
+
+ <para>
+ Writing an observer for this event may be useful for setting additional field values on the entity, which aren't set
+ as part of the standard <literal>createUser()</literal> functionality.
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>JpaIdentityStore.EVENT_USER_CREATED</title>
+
+ <para>
+ This event is also raised in response to calling <literal>IdentityManager.createUser()</literal>. However, it is
+ raised after the user entity has already been persisted to the database. Like the <literal>EVENT_PRE_PERSIST_USER</literal>
+ event, it also passes the entity instance as an event parameter. It may be useful to observe this event if you also
+ need to persist other entities that reference the user entity, for example contact detail records or other user-specific
+ data.
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>JpaIdentityStore.EVENT_USER_AUTHENTICATED</title>
+
+ <para>
+ This event is raised when calling <literal>IdentityManager.authenticate()</literal>. It passes the user entity instance
+ as the event parameter, and is useful for reading additional properties from the user entity that is being authenticated.
+ </para>
+ </sect4>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>LdapIdentityStore</title>
+
+ <para>
+ This identity store implementation is designed for working with user records stored in an LDAP directory. It is very
+ highly configurable, allowing great flexibility in how both users and roles are stored in the directory. The following
+ sections describe the configuration options for this identity store, and provide some configuration examples.
+ </para>
+
+ <sect3>
+ <title>Configuring LdapIdentityStore</title>
+
+ <para>
+ The following table describes the available properties that can be configured in <literal>components.xml</literal> for
+ <literal>LdapIdentityStore</literal>.
+ </para>
+
+ <table>
+ <title>LdapIdentityStore Configuration Properties</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Property</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>server-address</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ The address of the LDAP server, defaults to <literal>localhost</literal>.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>server-port</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ The port number that the LDAP server is listening on, defaults to 389.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>user-context-DN</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ The Distinguished Name (DN) of the context containing user records. The default value is
+ "<literal>ou=Person,dc=acme,dc=com</literal>".
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>user-DN-prefix</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ This value is prefixed to the front of the username to locate the user's record.
+ The default value is "<literal>uid=</literal>".
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>user-DN-suffix</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ This value is appended to the end of the username to locate the user's record. The default
+ value is "<literal>,ou=Person,dc=acme,dc=com</literal>".
+ </para>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Writing your own IdentityStore implementation</title>
+
+ <para>
+
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Authentication with Identity Management</title>
+
+ <para>
+ If you are using the Identity Management features in your Seam application, then it is not required
+ to provide an authenticator component (see previous Authentication section) to enable authentication.
+ Simply omit the <literal>authenticator-method</literal> from the <literal>identity</literal> configuration
+ in <literal>components.xml</literal>, and the <literal>SeamLoginModule</literal> will by default
+ use <literal>IdentityManager</literal> to authenticate your application's users, without any special
+ configuration required.
+ </para>
+ </sect2>
</sect1>
<sect1>
@@ -1028,7 +1655,46 @@
</sect3>
</sect2>
+
+ <sect2>
+ <title>Rule-based Permissions</title>
+
+ <sect3>
+ <title>Configuration</title>
+
+ </sect3>
+
+ <sect3>
+ <title>Requirements</title>
+
+ <para>
+ If using the rule-based permission features provided by Seam Security, the following jar files are required to be
+ distributed with your project:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>drools-compiler.jar</para>
+ </listitem>
+ <listitem>
+ <para>drools-core.jar</para>
+ </listitem>
+ <listitem>
+ <para>janino.jar</para>
+ </listitem>
+ <listitem>
+ <para>antlr-runtime.jar</para>
+ </listitem>
+ <listitem>
+ <para>mvel14.jar</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect3>
+
+ </sect2>
+
</sect1>
<sect1>
@@ -1666,7 +2332,7 @@
<imagedata fileref="images/security-identitymanager.png" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../shared/images/security-identitymanager.png" align="center"/>
+ <imagedata fileref="images/security-identitymanager.png" align="center"/>
</imageobject>
</mediaobject>
@@ -1702,7 +2368,7 @@
<imagedata fileref="images/security-useraccount.png" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../shared/images/security-useraccount.png" align="center"/>
+ <imagedata fileref="images/security-useraccount.png" align="center"/>
</imageobject>
</mediaobject>
@@ -1715,7 +2381,7 @@
<imagedata fileref="images/security-useraccountschema.png" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../shared/images/security-useraccountschema.png" align="center"/>
+ <imagedata fileref="images/security-useraccountschema.png" align="center"/>
</imageobject>
</mediaobject>
@@ -2515,7 +3181,7 @@
<imagedata fileref="images/security-usermanager1.png" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../shared/images/security-usermanager1.png" align="center"/>
+ <imagedata fileref="images/security-usermanager1.png" align="center"/>
</imageobject>
</mediaobject>
@@ -2528,7 +3194,7 @@
<imagedata fileref="images/security-usermanager2.png" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../shared/images/security-usermanager2.png" align="center"/>
+ <imagedata fileref="images/security-usermanager2.png" align="center"/>
</imageobject>
</mediaobject>
More information about the seam-commits
mailing list