Acegi预设的是通过JdbcDaoImpl访问数据库进行身份验证,我们首先来看下配置文件
<!-- 数据库验证身份采用内存DAO -->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<ref bean="jdbcDaoImpl"/>
</property>
<property name="userCache">
<ref bean="userCache"/>
</property>
</bean>
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="usersByUsernameQuery">
<value>
SELECT username,password,enabled FROM user WHERE username=?
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
SELECT username, rolename
FROM user u, role r, user_role ur
WHERE u.id = ur.user_id
and r.id = ur.role_id
and u.username = ?
</value>
</property>
</bean>
从配置及源码可以看出JdbcDaoImpl都是实现了UserDetailsService接口, 而这个接口里只定义了一个方法:UserDetails loadUserByUsername(String username) 就是根据用户名加载UserDetails对象。要获取更多的用户信息可以通过扩展JdbcDaoImpl,重写UsersByUsernameMapping方法来封装UserDetails对象。首先需要扩展UserDetails接口, 并扩展org.acegisecurity.userdetails.User
public interface IUserDetails extends UserDetails {
public void setUsername_cn(String username_cn);
public String getUsername_cn();
public String getUsername();
public void setUsername(String username);
public GrantedAuthority[] getAuthorities();
public void setAuthorities(GrantedAuthority[] authorities);
}
public class UserDetailsImpl extends User implements IUserDetails {
private String username_cn;
private String username;
private GrantedAuthority[] authorities;
public UserDetailsImpl(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked, GrantedAuthority[] authorities)
throws IllegalArgumentException {
super(username, password, enabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, authorities);
setUsername(username);
setAuthorities(authorities);
}
public UserDetailsImpl(String username_cn, String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked, GrantedAuthority[] authorities)
throws IllegalArgumentException {
super(username, password, enabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, authorities);
this.username_cn = username_cn;
setUsername(username);
setAuthorities(authorities);
}
public GrantedAuthority[] getAuthorities() {
return authorities;
}
public void setAuthorities(GrantedAuthority[] authorities) {
this.authorities = authorities;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername_cn() {
return username_cn;
}
public void setUsername_cn(String username_cn) {
this.username_cn = username_cn;
}
}
接着通过扩展JdbcDaoImpl,重写IUserDetails loadUserByUsername(String username)返回我们所扩展的UserDetail对象
public class AcegiJdbcDaoImpl extends JdbcDaoImpl {
.
public IUserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
List users = usersByNameMapping.execute(username);
if (users.size() == 0) {
throw new UsernameNotFoundException("User not found");
}
IUserDetails user = (IUserDetails) users.get(0); // contains no GrantedAuthority[]
List dbAuths = rolesByUsernameMapping.execute(user.getUsername());
addCustomAuthorities(user.getUsername(), dbAuths);
if (dbAuths.size() == 0) {
throw new UsernameNotFoundException("User has no GrantedAuthority");
}
GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]);
user.setAuthorities(arrayAuths);
if (!usernameBasedPrimaryKey) {
user.setUsername(username);
}
return user;
}
protected class UsersByUsernameMapping extends MappingSqlQuery {
protected UsersByUsernameMapping(DataSource ds) {
super(ds, usersByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
String username = rs.getString("username");
String username_cn = rs.getString("username_cn");
String password = rs.getString(3);
boolean enabled = rs.getBoolean("enabled");
IUserDetails user = new UserDetailsImpl(username, password, enabled, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
user.setUsername_cn(username_cn);
return user;
}
}
}
相应的配置文件更改为
AcegiJdbcDaoImpl bean
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<bean id="userDetailsService"
class="com.emms.security.acegi.AcegiJdbcDaoImpl">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="usersByUsernameQuery">
<value>
SELECT distinct(u.username), u.username_cn, password, enabled from emms_role r, user_role ur, emms_user u
where r.id = ur.role_id and ur.user_id = u.username and u.username = ?
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
SELECT u.username, r.rolename FROM user_role ur, emms_user u, emms_role r
WHERE ur.user_id = u.username and ur.role_id = r.id and u.username = ?
</value>
</property>
</bean>
posted on 2008-03-11 09:29
扭曲的铅笔 阅读(1525)
评论(1) 编辑 收藏 所属分类:
Spring