Friday, May 25, 2007

ACEGI Authentication Provider Examples

Acegi provides a very flexible way to configure the authentication provider. By default it provides two implementations of the authentication provider

- InMemoryDaoImpl : Retrieves user details from an in-memory list created by the bean context. So basically the list of users and their passwords are specified in the bean configuration file. (http://www.acegisecurity.org/multiproject/acegi-security/apidocs/org/acegisecurity/userdetails/memory/InMemoryDaoImpl.html). See below for sample bean configuration

<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,ROLE_TELLER
scott=wombat,ROLE_TELLER
peter=opal,disabled,ROLE_TELLER
</value>
</property>
</bean>


- JdbcDaoImpl : Retrieves user details (username, password, enabled flag, and authorities) from a JDBC location. A default database structure is assumed, which most users of this class will need to override, if using an existing schema. This may be done by setting the default query strings used. If this does not provide enough flexibility, another strategy would be to subclass this class and override the MappingSqlQuery instances used, via the initMappingSqlQueries() extension point. (http://www.acegisecurity.org/multiproject/acegi-security/apidocs/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.html). See below for code sample to configure using a jdbc driver or a datasource. Irrespective of the database used and how a DataSource is obtained, a standard schema must exist in the database

-- USING JDBC Driver
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>org.hsqldb.jdbcDriver</value></property>
<property name="url"><value>jdbc:hsqldb:hsql://localhost:9001</value></property>
<property name="username"><value>sa</value></property>
<property name="password"><value></value></property>
</bean>

-- Using Datasource
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>


- Custom implementation : The above two implementations basically implement the UserDetailsService interface. If you have complex needs (such as a special schema or would like a certain UserDetails implementation returned), you'd be better off writing your own UserDetailsService(http://www.acegisecurity.org/multiproject/acegi-security/apidocs/index.html?org/acegisecurity/userdetails/UserDetailsService.html).

Code Sample:

<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
</list>
</property>
</bean>

<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService"><ref bean="UserService"/></property>
</bean>

<bean id="UserService" class = "com.icrossing.xxx.CustomAuthenticationProvider"/>

-- Sample implementation

class CustomAuthenticationProvider implements org.acegisecurity.userdetails.UserDetailsService
{
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException, DataAccessException
{
User user = null;
GrantedAuthority[] grantedAuthorities = null;
try {
user = getUserDAO().lookupUser(userId);

if(user==null) {
throw new UsernameNotFoundException("Invalid User");
}

Set roles = user.getRoles();
int i = 0;
grantedAuthorities = new GrantedAuthority[roles.size()];
for (Iterator iter = roles.iterator(); iter.hasNext(); i++) {
Role role = (Role) iter.next();

GrantedAuthority authority = new GrantedAuthorityImpl(role.getRole());
grantedAuthorities[i] = authority;
}
} catch (DataStoreException e) {
throw new DataRetrievalFailureException("Cannot loadUserByUsername userId:"+userId+ " Exception:" + e.getMessage(), e);
}

UserDetails userDetails = new org.acegisecurity.userdetails.User(
user.getUserId(),
user.getPassword(),
user.isEnabled(), //enabled
user.isEnabled(), //accountNonExpired
user.isEnabled(), //credentialsNonExpired
user.isEnabled(), //accountNonLocked
grantedAuthorities
);
return userDetails;
}
}

No comments:

Post a Comment