平臺管理後臺的訪問控制設計
這裡的訪問控制設計使用了Spring Secutiry來實現,這些內容與第10章SSO設計中的訪問控制部分的實現方法相差不多,不同之處在於這裡並不需要OAuth 2,而對許可權管理的設計也使用了一種更為簡便的方法來實現。下面略過一些相同的地方,只針對不同點進行說明。這些設計都是在模組manage-web 中實現的。
在訪問控制中使用操作員
建立一個MyUserDetails類,實現Spring Secutiry的UserDetails,從而匯入Operators使用者及其許可權管理,程式碼如下所示:
public class MyUserDetails implements UserDetails {private String username;private String password;private Collection<? extends GrantedAuthority> authorities;private Operators operators;public MyUserDetails(String username,String password, collection<? extendsGrantedAuthority>authorities,Operators operators) {this.username = username;this.password = password;this.authorities =authorities;this.operators = operators;this.operators.setPassword(null);)...}
建立一個 MyUserDetailsService服務類,並在配置類SecurityConfiguration中進行引用。這樣就可以讓Spring Secutiry使用我們定義的使用者及其許可權進行安全訪問控制認證了。具體的實現細節可參考前文的SSO設計。
平臺管理後臺的許可權管理設計
這裡的許可權管理使用了一種較為簡單的方法來實現,即透過使用配置引數實現許可權管理,實現方法如下。
首先,在模組的應用配置中增加如下所示的配置項:
securityconfig:logoutsuccssurl:/permitall:-/druid/*★- /bbs**deniedpage:/denyurlroles:/**/new/** =admins;/★*/edit/**=admins, editors;/**/delete/** =admins
這些配置引數由自定義的一個配置類 SecuritySettings 實現。
在控制器的設計中,同樣需要使用這些關鍵字設定URL,例如下面所示的一些@RequestMapping 設計:
@RequestMapping( "/new")CRequestMapping(value="/edit/{id] ")@RequestMapping(value="/update",method = RequestMethod.POST)@RequestMapping(value=" /delete/{id} ")
其次,在安全資源管理的元資料管理CustomSecurityMetadataSource中,使用如下所示的設計:
public CustomsecurityMetadataSource (String urlroles){super();this.urlroles =urlroles;resourceMap = loadResourceMatchAuthority();private Map<String, Collection<ConfigAttribute>>loadResourceMatchAuthority({Map<String, Collection<ConfigAttribute>>map = new HashMap<String,Collection<ConfigAttribute>>(0);if (urlroles !=null && !urlroles.isEmpty()){String[] resouces = urlroles.split(";");for(String resource : resouces){String[]urls = resource.split("=");String[roles = urls[1].split(",");Collection<ConfigAttribute> list = newArrayList<ConfigAttribute>();for(String role :roles){ConfigAttribute config =new SecurityConfig (role.trim());list.add (config);//key: url,value: rolesmap.put(urls[0].trim(), list);}else{logger.error("'securityconfig.urlroles' must be set");}logger.info ( "Loaded UrlRoles Resources. ");return map;}
這個設計表示,當系統啟動時,匯入上面許可權配置的資料作為安全管理的元資料,給後面的許可權檢查提供依據。
最後,在許可權檢查CustomAccessDecisionManager的設計中,使用如下所示的設計:
public class CustomAccessDecisionManager implements AccessDecisionManager{protected Log log = LogFactory.getLog (getClass());@overridepublic void decide (Authentication authentication, 0bject object,Collection<configAttribute>configAttributes)throws AccessDeniedException,InsufficientAuthenticationException tif(configAttributes == null) {return;}//config urlrolesIterator<ConfigAttribute>iterator = configAttributes.iterator();while (iterator.hasNext()){ConfigAttribute configAttribute = iterator.next();//need roleString needRole = configAttribute.getAttribute();//user rolesfor (GrantedAuthority ga : authentication.getAuthorities())Iif (needRole.equals(ga.getAuthority())) {return;}}log.info("need role is " + needRole);}throw new AccessDeniedException ( "Cannot Access!");}}
當用戶訪問的資源中包含安全管理的元資料時,就檢查使用者的角色列表中是否有與之匹配的角色,以此達到許可權驗證的目的。
這種簡化的設計要求我們在建立角色時,其名字必須與配置中的名字相匹配,即使用前面配置中的admins和 editors。
如果想要透過資料管理的方式控制權限,實現更加豐富的許可權管理功能,則可以參照10.4節中的內容。
在完成上面所有設計後,就可以開始進行測試了。
直接啟動manage-web應用,啟動成功之後,在瀏覽中輸入如下所示的連結登入系統:
http://localhost:8099
使用前面單元測試時生成的使用者名稱admin即可登入系統。登入系統後可以對操作員及其角色等資料進行管理,如圖11-1所示。