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 
扭曲的铅笔 阅读(1541) 
评论(1)  编辑  收藏  所属分类: 
Spring