在SpringSide 3的官方文档中,说安全框架使用的是Spring Security 2.0。乍一看,吓了我一跳,以为Acegi这么快就被淘汰了呢。上搜索引擎一搜,发现原来Spring Security 2.0就是Acegi 2.0。悬着的心放下来了。虽然SpringSide 3中关于Acegi的配置文件看起来很不熟悉,但是读了Acegi 2.0的官方文档后,一切都释然了。 对于这两种管理器,那也是不需要我们写代码的,Acegi也提供了现成的类。那么大家又奇怪了:又是现成的,那怎么和我的数据库关联起来呢?别着急,其实这两个管理器自己也不做事,认证管理器把任务交给了Provider,而决策管理器则把任务交给了Voter,如下图: 现在我要告诉你们,这里的Provider和Voter也是不需要我们写代码的。不要崩溃,快到目标了。Acegi提供了多个Provider的实现类,如果我们想用数据库来储存用户的认证数据,那么我们就选择DaoAuthenticationProvider。对于Voter,我们一般选择RoleVoter就够用了,它会根据我们配置文件中的设置来决定是否允许某一个用户访问制定的Web资源。 package personal.youxia.service.security;
import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Required; import org.springframework.dao.DataAccessException; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsService; import org.springframework.security.userdetails.UsernameNotFoundException; import personal.youxia.entity.user.Authority; import personal.youxia.entity.user.Role; import personal.youxia.entity.user.User; import personal.youxia.service.user.UserManager; /** * 实现SpringSecurity的UserDetailsService接口,获取用户Detail信息. * * @author calvin */ public class UserDetailServiceImpl implements UserDetailsService { private UserManager userManager; public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException { User user = userManager.getUserByLoginName(userName); if (user == null ) throw new UsernameNotFoundException(userName + " 不存在 " ); List < GrantedAuthority > authsList = new ArrayList < GrantedAuthority > (); for (Role role : user.getRoles()) { for (Authority authority : role.getAuths()) { authsList.add( new GrantedAuthorityImpl(authority.getName())); } } // 目前在MultiDatabaseExample的User类中没有enabled, accountNonExpired,credentialsNonExpired, accountNonLocked等属性 // 暂时全部设为true,在需要时才添加这些属性. org.springframework.security.userdetails.User userdetail = new org.springframework.security.userdetails.User( user.getLoginName(), user.getPassword(), true , true , true , true , authsList .toArray( new GrantedAuthority[authsList.size()])); return userdetail; } @Required public void setUserManager(UserManager userManager) { this .userManager = userManager; } } 最后再来说说这个命名的问题,我对Authentication和Authority这两个单词比较反感,两个原因,一是因为它们太生僻了,二是因为它们长得太像了,明明一个是认证,一个是授权,意思相差很远,外貌却如此相似,确实很烦人。如果让我来选择,我喜欢Privilege这个单词,在我刚使用MySQL的时候就跟它很熟了,所以在我的项目中,我可能会用Privilege来代替Authority。如果我们只使用User-Role两级关系,使用RoleVoter默认的ROLE_前缀当然没有关系,如果是像白衣这样是用三层关系,最好还是把这个前缀改一改,以免混淆。 |
|
来自: goldbomb > 《Spring Security 》