|
在SpringSide 3的官方文檔中,說安全框架使用的是Spring Security 2.0。乍一看,嚇了我一跳,以為Acegi這么快就被淘汰了呢。上搜索引擎一搜,發(fā)現(xiàn)原來Spring Security 2.0就是Acegi 2.0。懸著的心放下來了。雖然SpringSide 3中關(guān)于Acegi的配置文件看起來很不熟悉,但是讀了Acegi 2.0的官方文檔后,一切都釋然了。 對(duì)于這兩種管理器,那也是不需要我們寫代碼的,Acegi也提供了現(xiàn)成的類。那么大家又奇怪了:又是現(xiàn)成的,那怎么和我的數(shù)據(jù)庫關(guān)聯(lián)起來呢?別著急,其實(shí)這兩個(gè)管理器自己也不做事,認(rèn)證管理器把任務(wù)交給了Provider,而決策管理器則把任務(wù)交給了Voter,如下圖: 現(xiàn)在我要告訴你們,這里的Provider和Voter也是不需要我們寫代碼的。不要崩潰,快到目標(biāo)了。Acegi提供了多個(gè)Provider的實(shí)現(xiàn)類,如果我們想用數(shù)據(jù)庫來儲(chǔ)存用戶的認(rèn)證數(shù)據(jù),那么我們就選擇DaoAuthenticationProvider。對(duì)于Voter,我們一般選擇RoleVoter就夠用了,它會(huì)根據(jù)我們配置文件中的設(shè)置來決定是否允許某一個(gè)用戶訪問制定的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; /** * 實(shí)現(xiàn)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等屬性 // 暫時(shí)全部設(shè)為true,在需要時(shí)才添加這些屬性. 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; } } 最后再來說說這個(gè)命名的問題,我對(duì)Authentication和Authority這兩個(gè)單詞比較反感,兩個(gè)原因,一是因?yàn)樗鼈兲Я?,二是因?yàn)樗鼈冮L(zhǎng)得太像了,明明一個(gè)是認(rèn)證,一個(gè)是授權(quán),意思相差很遠(yuǎn),外貌卻如此相似,確實(shí)很煩人。如果讓我來選擇,我喜歡Privilege這個(gè)單詞,在我剛使用MySQL的時(shí)候就跟它很熟了,所以在我的項(xiàng)目中,我可能會(huì)用Privilege來代替Authority。如果我們只使用User-Role兩級(jí)關(guān)系,使用RoleVoter默認(rèn)的ROLE_前綴當(dāng)然沒有關(guān)系,如果是像白衣這樣是用三層關(guān)系,最好還是把這個(gè)前綴改一改,以免混淆。 |
|
|