SeamFramework.orgCommunity Documentation
The majority of the Security API is centered around the Identity
bean. This bean represents the
identity of the current user, the default implementation of which is a session-scoped, named bean. This
means that once logged in, a user's identity is scoped to the lifecycle of their current session. The two most
important methods that you need to know about at this stage in regard to authentication are login()
and
logout()
, which as the names suggest are used to log the user in and out, respectively.
As the default implementation of the Identity
bean is named, it may be referenced via an EL
expression, or be used as the target of an EL action. Take the following JSF code snippet for example:
<h:commandButton action="#{identity.login}" value="Log in"/>
This JSF command button would typically be used in a login form (which would also contain inputs for the user's username and password) that allows the user to log into the application.
The bean type of the Identity
bean is org.jboss.seam.security.Identity
. This
interface is what you should inject if you need to access the Identity
bean from your
own beans. The default implementation is org.jboss.seam.security.IdentityImpl
.
The other important bean to know about right now is the Credentials
bean. Its' purpose is to
hold the user's credentials (such as their username and password) before the user logs in. The default implementation
of the Credentials
bean is also a session-scoped, named bean (just like the Identity
bean).
The Credentials
bean has two properties, username
and credential
that are used to hold the current user's username and credential (e.g. a password) values. The default implementation of
the Credentials
bean provides an additional convenience property called password
,
which may be used in lieu of the credential
property when a simple password is required.
The bean type of the Credential
bean is org.jboss.seam.security.Credentials
. The
default implementation for this bean type is org.jboss.seam.security.CredentialsImpl
.
Also, as credentials may come in many forms (such as passwords, biometric data such as that from a fingerprint reader, etc) the
credential
property of the Credentials
bean must be able to support each variation,
not just passwords. To allow for this, any credential that implements the org.picketlink.idm.api.Credential
interface is a valid value for the credential
property.
The Seam Security module provides the following built-in Authenticator
implementations:
org.jboss.seam.security.jaas.JaasAuthenticator
- used to authenticate against a JAAS
configuration defined by the container.
org.jboss.seam.security.management.IdmAuthenticator
- used to authenticate against an
Identity Store using the Identity Management API. See the Identity Management chapter for details on how
to configure this authenticator.
org.jboss.seam.security.external.openid.OpenIdAuthenticator
(provided by the external module) - used
to authenticate against an external OpenID provider, such as Google, Yahoo, etc. See the External Authentication chapter
for details on how to configure this authenticator.
The Identity
bean has an authenticatorClass
property, which if set will be used
to determine which Authenticator
bean implementation to invoke during the
authentication process. This property may be set by configuring it with a predefined authenticator type,
for example by using Solder XML Config. The following XML configuration example shows how you would configure the
Identity
bean to use the com.acme.MyCustomerAuthenticator
bean for authentication:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="urn:java:ee"
xmlns:security="urn:java:org.jboss.seam.security"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
<security:IdentityImpl>
<s:modifies/>
<security:authenticatorClass>com.acme.MyCustomAuthenticator</security:authenticatorClass>
</security:IdentityImpl>
</beans>
Alternatively, if you wish to be able to select the Authenticator
to authenticate with by
specifying the name of the Authenticator
implementation (i.e. for those annotated with
the @Named
annotation), the authenticatorName
property may be set instead.
This might be useful if you wish to offer your users the choice of how they would like to authenticate, whether it
be through a local user database, an external OpenID provider, or some other method.
The following example shows how you might configure the authenticatorName
property with the
Seam Config module:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="urn:java:ee"
xmlns:security="urn:java:org.jboss.seam.security"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
<security:IdentityImpl>
<s:modifies/>
<security:authenticatorName>openIdAuthenticator</security:authenticatorName>
</security:IdentityImpl>
</beans>
If neither the authenticatorClass
or authenticatorName
properties are set,
then the authentication process with automatically use a custom Authenticator
implementation, if
the developer has provided one (and only one) within their application.
If neither property is set, and the user has not provided a custom Authenticator
, then the
authentication process will fall back to the Identity Management API to attempt to authenticate the user.
All Authenticator
implementations must implement the org.jboss.seam.security.Authenticator
interface. This interface defines the following methods:
public interface Authenticator {
void authenticate();
void postAuthenticate();
User getUser();
AuthenticationStatus getStatus();
}
The authenticate()
method is invoked during the authentication process and is responsible for performing the
work necessary to validate whether the current user is who they claim to be.
The postAuthenticate()
method is invoked after the authentication process has already completed, and
may be used to perform any post-authentication business logic, such as setting session variables, logging, auditing, etc.
The getUser()
method should return an instance of org.picketlink.idm.api.User
,
which is generally determined during the authentication process.
The getStatus()
method must return the current status of authentication, represented by the
AuthenticationStatus
enum. Possible values are SUCCESS
, FAILURE
and DEFERRED
. The DEFERRED
value should be used for special circumstances, such as
asynchronous authentication as a result of authenticating against a third party as is the case with OpenID, etc.
The easiest way to get started writing your own custom authenticator is to extend the
org.jboss.seam.security.BaseAuthenticator
abstract class. This class implements the
getUser()
and getStatus()
methods for you, and provides
setUser()
and setStatus()
methods for setting both the user and status values.
An Authenticator
implementation cannot be a stateless session bean.
To access the user's credentials from within the authenticate()
method, you can inject the
Credentials
bean like so:
@Inject Credentials credentials;
Once the credentials are injected, the authenticate()
method is responsible for checking that
the provided credentials are valid. Here is a complete example:
public class SimpleAuthenticator extends BaseAuthenticator implements Authenticator {
@Inject Credentials credentials;
@Override
public void authenticate() {
if ("demo".equals(credentials.getUsername()) &&
credentials.getCredential() instanceof PasswordCredential &&
"demo".equals(((PasswordCredential) credentials.getCredential()).getValue())) {
setStatus(AuthenticationStatus.SUCCESS);
setUser(new SimpleUser("demo"));
}
}
}
The above code was taken from the simple authentication example, included in the Seam Security distribution.
In the above code, the authenticate()
method checks that the user has provided a username of
demo and a password of demo. If so, the authentication is deemed as successful
and the status is set to AuthenticationStatus.SUCCESS
, and a new SimpleUser
instance
is created to represent the authenticated user.
The Authenticator
implementation must return a non-null value when
getUser()
is invoked if authentication is successful. Failure to return a non-null value
will result in an AuthenticationException
being thrown.