From seam-commits at lists.jboss.org Fri Jun 20 00:08:36 2008 Content-Type: multipart/mixed; boundary="===============5111549992434939753==" MIME-Version: 1.0 From: seam-commits at lists.jboss.org To: seam-commits at lists.jboss.org Subject: [seam-commits] Seam SVN: r8396 - trunk/doc/Seam_Reference_Guide/en-US. Date: Fri, 20 Jun 2008 00:08:36 -0400 Message-ID: --===============5111549992434939753== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: shane.bryzak(a)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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/doc/Seam_Reference_Guide/en-US/Security.xml 2008-06-19 20:14:32 U= TC (rev 8395) +++ trunk/doc/Seam_Reference_Guide/en-US/Security.xml 2008-06-20 04:08:36 U= TC (rev 8396) @@ -3,82 +3,54 @@ Security = - - The Seam Security API is an optional Seam feature that provides authen= tication and authorization features - for securing both domain and page resources within your Seam project. - - Overview - + = - Seam Security provides two different modes of operation: + The Seam Security API provides a multitude of security-related featu= res for your Seam-based application, covering = + such areas as: - + = - simplified mode - this mode supports authen= tication services - and simple role-based security checks. + Authentication - an extensible, JAAS-based authentication layer = that allows users to authenticate + against any security provider. - advanced mode - 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 u= sers and roles at runtime. - - - - Which mode is right for my application? - - - 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 wh= o are logged in, or who belong to a certain role, - then the simplified mode will probably be sufficient. The advanta= ges of this is a more simplified configuration, - significantly less libraries to include, and a smaller memory foot= print. - - - - If on the other hand, your application requires security checks ba= sed on contextual state or complex business rules, - then you will require the features provided by the advanced mode. - - - - - - Requirements - - - If using the advanced mode features of Seam Security, the following = jar files are required to be configured as modules in - application.xml. If you are using Seam Security = in simplified mode, these are not - required: - - - - drools-compiler.jar + + Authorization - an extremely comprehensive authorization framewo= rk, supporting user roles, persistent and + rule-based permissions, and a pluggable permission resolver for = easily implementing customised security logic. + - drools-core.jar + + Permission Management - a set of built-in Seam components to all= ow easy management of an application's = + security policy. + = - janino.jar + + CAPTCHA support - to assist in the prevention of automated softw= are/scripts abusing your Seam-based site. + - antlr-runtime.jar + + And much more + - - mvel14.jar - - - + = + = - For web-based security, jboss-seam-ui.jar must al= so be included in the application's war file. - + This chapter will cover each of these features in detail. + = = - = @@ -105,7 +77,7 @@ - + = Authentication = @@ -114,17 +86,22 @@ and as such provide a robust and highly configurable API for handlin= g user authentication. However, for less complex authentication requirements Seam offers a much more simplified metho= d of authentication that hides the complexity of JAAS. - + = - Configuration + Configuring an Authenticator component = + + 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). + + - The simplified authentication method uses a built-in JAAS login mo= dule, SeamLoginModule, which + The simplified authentication method provided by Seam uses a built= -in JAAS login module, SeamLoginModule, 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 p= rovided by your own application. Configuring this - simplified form of authentication requires the identity component to be configured in - components.xml: + write an authentication method using the entity classes that are p= rovided by your own application, or alternatively to = + authenticate against some other third party provider. Configuring= this simplified form of authentication requires the = + identity component to be configured in components.xml: = ]]> = - If you wish to use the advanced security features such as rule-bas= ed permission checks, all you need - to do is include the Drools (JBoss Rules) jars in your classpath, = and add some additional configuration, - described later. - - - The EL expression #{authenticator.authenticate}= is a method binding indicating that the authenticate method of the authent= icator component will be used to authenticate the user. @@ -161,29 +132,31 @@ components.xml specifies which method will be u= sed by SeamLoginModule to authenticate users. This method takes no parameters, and is ex= pected to return a boolean indicating whether authentication is successful or not. The user's username = and password can be obtained from - Identity.instance().getUsername() and = Identity.instance().getPassword(), + Credentials.getUsername() and Credenti= als.getPassword(), respectively. Any roles that the user is a member of should be as= signed using - Identity.instance().addRole(). Here's a complet= e example of an authentication method - inside a JavaBean component: + Identity.addRole(). Here's a complete example o= f an authentication method + inside a POJO component: = NoRes= ultException thrown, the authentication method returns false to indicate= the authentication failed. + = + + When writing an authenticator method, it is important that it is k= ept 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 i= nvoked multiple times during + a single request. Because of this, any special code that should e= xecute upon a successful or + failed authentication should be written by implementing an event o= bserver. See the section on + Security Events further down in this chapter for more information = about which events are + raised by Seam Security. + = Identity.addRole() @@ -227,24 +210,19 @@ + = + + If the current session is already authenticated, then calling Identity.addRole() will + have the expected effect of immediate granting the current user = the specified role. + = = - Special Considerations + Writing an event observers for security-related events</tit= le> = <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 ho= w 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 informatio= n 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 use= r 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 Authent= icator component itself. + You can find more information about security-related events late= r in this chapter. + </para> </sect3> = </sect2> @@ -265,21 +248,21 @@ <title>Writing a login form = - The Identity component provides both u= sername and password + The credentials component provides both username and password 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 properti= es are set, calling the - identity.login() method will authenticate the u= ser using the provided credentials. + username and password fields on a login form. Once these properti= es are set, calling = + identity.login() will authenticate the user usi= ng the provided credentials. Here's an example of a simple login form: = - + =
- +
=
@@ -288,13 +271,13 @@ = Similarly, logging out the user is done by calling #{iden= tity.logout}. Calling this - action will clear the security state of the currently authenticate= d user. + action will clear the security state of the currently authenticate= d user, and invalidate the user's session. = = - Simplified Configuration - Summary + Configuration Summary So to sum up, there are the three easy steps to configure authenti= cation: @@ -509,9 +492,653 @@ itself using the configured JAAS security policy. + + + = + + Identity Management + = + + 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 identityManager 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 listi= ng users and roles. + + = + + Configuring IdentityManager + = + = + The identityManager component allows for separa= te 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 d= irectory, yet have their roles = + loaded from another identity store, such as a relational database. + + = + + Seam provides two IdentityStore implementations= out of the box; = + JpaIdentityStore uses a relational database to = store user and role information, = + and is the default identity store that is used if nothing is expli= citly configured in the + identityManager component. The other implement= ation that is provided is = + LdapIdentityStore, which uses an LDAP directory= to store users and roles. + + = + + There are two configurable properties for the identityMan= ager component - = + identityStore and roleIdentityStore. The value for these + properties must be an EL expression referring to a Seam component = implementing the + IdentityStore interface. As already mentioned, + if left unconfigured then JpaIdentityStore will= be assumed by default. If + only the identityStore property is configured, = then the same value will be used for + roleIdentityStore also. For example, the follo= wing entry in + components.xml will configure identity= Manager to use + an LdapIdentityStore for both user-related and = role-related operations: + = + + ]]> + = + + The following example configures identityManager to use an LdapIdentityStore + for user-related operations, and JpaIdentityStore for role-related operations: + + = + + ]]> + = + + The following sections explain both of these identity store implem= entations in greater detail. + + = + = + + JpaIdentityStore + = + + 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 d= esign, allowing a great deal of = + flexibility in the underlying table structure. This is achieved t= hrough the use of a set of special + annotations, allowing entity beans to be configured to store user = and role records. = + + = + + Configuring JpaIdentityStore + = + + JpaIdentityStore requires that both the user-class and = + role-class properties are configured. These = properties should refer to the + entity classes that are to be used to store both user and role r= ecords, respectively. The following + example shows the configuration from components.xml in the SeamSpace example: + + = + + ]]> + = + + = + + Configuring the Entities + = + + As already mentioned, a set of special annotations are used to c= onfigure entity beans for storing + users and roles. The following table lists each of the annotati= ons, and their descriptions. + + = + + User Entity Annotations + = + + + + + = + + + + Annotation + + + Status + + + Description + + + + = + = + + + + @UserPrincipal + + + + Required + + + + This annotation marks the field or method containing t= he user's username. + + + = + = + + + + @UserPassword + + + + Required + + + + This annotation marks the field or method containing t= he user's password. It allows a hash + algorithm to be specified for password hashing. Possi= ble values for hash are + md5 and sha. E.= g: + = + + = + + + = + = + + + + @UserFirstName + + + + Optional + + + + This annotation marks the field or method containing t= he user's first name. + + + = + = + + + + @UserLastName + + + + Optional + + + + This annotation marks the field or method containing t= he user's last name. + + + = + = + + + + @UserEnabled + + + + Optional + + + + This annotation marks the field or method containing t= he enabled status of the user. This should be a boolean + property, and if not present then all user accounts ar= e assumed to be enabled. + + + = + = + + + + @UserRoles + + + + Required + + + + This annotation marks the field or method containing t= he roles of the user. This property will be described in = + more detail further down. + + + + + +
= + = + + Role Entity Annotations + = + + + + + = + + + + Annotation + + + Status + + + Description + + + + = + = + + + + @RoleName + + + + Required + + + + This annotation marks the field or method containing t= he name of the role. + + + = + = + + + + @RoleGroups + + + + Optional + + + + This annotation marks the field or method containing t= he group memberships of the role. + + + = + = + + + + @RoleConditional + + + + Optional + + + + This annotation marks the field or method indicating w= hether the role is conditional or not. + Conditional roles are explained later in this chapter. + + + = = + = + + +
= + = +
+ = + + Entity Bean Examples + = + + As mentioned previously, JpaIdentityStore is = designed to be as flexible as possible when + it comes to the database schema design of your user and role tab= les. This section looks at a number of + possible database schemas that can be used to store user and rol= e records. + + = + + Minimal schema example + = + + 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 = UserRoles. + + = + + + + + + + + = + = + roles; + = + @Id @GeneratedValue + public Integer getUserId() { return userId; } + public void setUserId(Integer userId) { this.userId =3D userId; } + = + @UserPrincipal + public String getUsername() { return username; } + public void setUsername(String username) { this.username =3D username; } + = + @UserPassword(hash =3D "md5") + public String getPasswordHash() { return passwordHash; } + public void setPasswordHash(String passwordHash) { this.passwordHash =3D= passwordHash; } + = + @UserRoles + @ManyToMany(targetEntity =3D Role.class) + @JoinTable(name =3D "UserRoles", = + joinColumns =3D @JoinColumn(name =3D "UserId"), + inverseJoinColumns =3D @JoinColumn(name =3D "RoleId")) + public Set getRoles() { return roles; } + public void setRoles(Set roles) { this.roles =3D roles; } +}]]> + = + + = + + Complex Schema Example + = + + This example builds on the above minimal example by including = all of the optional fields, and allowing + group memberships for roles. + + = + + + + + + + + = + = + roles; + private String firstname; + private String lastname; + private boolean enabled; + = + @Id @GeneratedValue + public Integer getUserId() { return userId; } + public void setUserId(Integer userId) { this.userId =3D userId; } + = + @UserPrincipal + public String getUsername() { return username; } + public void setUsername(String username) { this.username =3D username; } + = + @UserPassword(hash =3D "md5") + public String getPasswordHash() { return passwordHash; } + public void setPasswordHash(String passwordHash) { this.passwordHash =3D= passwordHash; } + = + @UserFirstName + public String getFirstname() { return firstname; } + public void setFirstname(String firstname) { this.firstname =3D firstnam= e; } + = + @UserLastName + public String getLastname() { return lastname; } + public void setLastname(String lastname) { this.lastname =3D lastname; } + = + @UserEnabled + public boolean isEnabled() { return enabled; } + public void setEnabled(boolean enabled) { this.enabled =3D enabled; } + = + @UserRoles + @ManyToMany(targetEntity =3D Role.class) + @JoinTable(name =3D "UserRoles", = + joinColumns =3D @JoinColumn(name =3D "UserId"), + inverseJoinColumns =3D @JoinColumn(name =3D "RoleId")) + public Set getRoles() { return roles; } + public void setRoles(Set roles) { this.roles =3D roles; } +}]]> + getGroups() { return groups; } + public void setGroups(Set groups) { this.groups =3D groups; } = + = +}]]> = + + = + + = + + JpaIdentityStore Events + = + + When using JpaIdentityStore as the identity s= tore implementation with IdentityManager, + a few events are raised as a result of invoking certain IdentityManager methods. + + = + + JpaIdentityStore.EVENT_PRE_PERSIST_USER + = + + This event is raised in response to calling IdentityM= anager.createUser(). 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 user-class configured for JpaIdentityStore. = + + = + + Writing an observer for this event may be useful for setting a= dditional field values on the entity, which aren't set + as part of the standard createUser() functi= onality. + + + = + + JpaIdentityStore.EVENT_USER_CREATED + = + + This event is also raised in response to calling Iden= tityManager.createUser(). However, it is = + raised after the user entity has already been persisted to the= database. Like the EVENT_PRE_PERSIST_USER + event, it also passes the entity instance as an event paramete= r. 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. + + + = + + JpaIdentityStore.EVENT_USER_AUTHENTICATED + = + + This event is raised when calling IdentityManager.aut= henticate(). It passes the user entity instance + as the event parameter, and is useful for reading additional p= roperties from the user entity that is being authenticated. + + + + = +
+ = + + LdapIdentityStore + = + + This identity store implementation is designed for working with us= er 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 stor= e, and provide some configuration examples. + + = + + Configuring LdapIdentityStore + = + + The following table describes the available properties that can = be configured in components.xml for + LdapIdentityStore. + + = + + LdapIdentityStore Configuration Properties + = + + + + = + + + + Property + + + Description + + + + = + = + + + + server-address + + + + + The address of the LDAP server, defaults to l= ocalhost. + + + + = + + + + server-port + + + + + The port number that the LDAP server is listening on, = defaults to 389. + + + + = + + + + user-context-DN + + + + + The Distinguished Name (DN) of the context containing = user records. The default value is + "ou=3DPerson,dc=3Dacme,dc=3Dcom". + + + + = + + + + user-DN-prefix + + + + + This value is prefixed to the front of the username to= locate the user's record. + The default value is "uid=3D". + + + + = + + + + user-DN-suffix + + + + + This value is appended to the end of the username to l= ocate the user's record. The default + value is ",ou=3DPerson,dc=3Dacme,dc=3Dcom". + + + + = + + +
= +
+
+ = + + Writing your own IdentityStore implementation + = + + = + + + = + + Authentication with Identity Management + = + + If you are using the Identity Management features in your Seam app= lication, then it is not required + to provide an authenticator component (see previous Authentication= section) to enable authentication. + Simply omit the authenticator-method from the <= literal>identity configuration + in components.xml, and the SeamLoginMo= dule will by default + use IdentityManager to authenticate your applic= ation's users, without any special + configuration required. + +
= @@ -1028,7 +1655,46 @@ = + = = + + Rule-based Permissions + = + + Configuration + = + + + + Requirements + = + + If using the rule-based permission features provided by Seam Sec= urity, the following jar files are required to be = + distributed with your project: + + = + + + drools-compiler.jar + + + drools-core.jar + + + janino.jar + + + antlr-runtime.jar + + + mvel14.jar + + + = + = + = + + = @@ -1666,7 +2332,7 @@ - + = @@ -1702,7 +2368,7 @@ - + = @@ -1715,7 +2381,7 @@ - + = @@ -2515,7 +3181,7 @@ - + = @@ -2528,7 +3194,7 @@ - + = --===============5111549992434939753==--