Spring Security 4 (03)—— 資源資訊
阿新 • • 發佈:2019-01-03
序言
這一篇主要是講資源的載入和認證
1.記憶體載入
<security:http auto-config="false" use-expressions="false" >
<security:intercept-url pattern="/system/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/financeReport/**" access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/**" access="ROLE_ADMIN" />
</security:http>
- auto-config=”true” : 自動生成登入頁面
- use-expressions=”true” : 表示access中支援hasRole這樣的函式
2.資料庫載入
在我們的實際專案中記憶體載入的方式肯定是不行的,我們使用者資訊都是存在資料庫中的。
這時我們就要配置自定義的資源載入方式。
<security:http auto-config="false" use-expressions="false" >
<!-- 替換 許可權驗證 過濾器 -->
<security:custom-filter ref="sysSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
</security:http>
<!-- 自定義認證管理,資源,許可權 -->
<bean id="sysSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor" >
<property name="authenticationManager" ref="sysAuthenticationManager" />
<property name="accessDecisionManager" ref="sysAccessDecisionManager" />
<property name="securityMetadataSource" ref="sysSecurityMetadataSource" />
</bean>
- authenticationManager 就是我上一章配置的認證管理器。
- accessDecisionManager 這個是我們自定義的資源認證管理器
- securityMetadataSource 這個是我們自定義的資源載入器
2.1 securityMetadataSource
要實現自定的資源載入只需要實現FilterInvocationSecurityMetadataSource介面的getAttributes()方法。
例:
/**
* 路徑-角色 載入
* @author Admin
*
*/
@Service
public class SysSecurityMetadataSource implements FilterInvocationSecurityMetadataSource{
private SysSecurityService sysSecurityServiceImp;
@Autowired
public SysSecurityMetadataSource(SysSecurityService sysSecurityServiceImp){
this.sysSecurityServiceImp =sysSecurityServiceImp;
}
/**
* 根據資源URL獲取角色
*/
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
FilterInvocation request = (FilterInvocation) object ;
//資源路徑
String url=request.getRequest().getServletPath();
//載入資源資訊
SysResources resource = sysSecurityServiceImp.findRolesByResourceURL(url);
Collection<ConfigAttribute> roles =new ArrayList<ConfigAttribute>();
if(resource == null){ //路徑 沒加許可權
roles.add(new SecurityConfig(SecurityFinal.ROLE_LOGIN));
}else if (resource.getAuthorities().size() ==0){ //路徑 無角色許可權
roles.add(new SecurityConfig(SecurityFinal.ROLE_NO_RIGHT));
}else{
for (String role : resource.getAuthorities()) {
roles.add(new SecurityConfig(SecurityFinal.ROLE_+role));
}
}
return roles;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
在這個地方我加了一個特殊的處理,當根據url查到null 時說明此路徑不在資源表中,此時將預設加入一個ROLE_LOGIN角色,(使用者登入後也有一個預設的ROLE_LOGIN角色,詳情請看上一章)。當根據url查到資訊,但是角色集合大小為0時說明此路徑在資源表中,只是沒有角色擁有次路徑,這時就加入一個ROLE_NO_RIGHT角色。
2.2 accessDecisionManager
要實現自定義的許可權認證只需要實現AccessDecisionManager介面的decide()
例:
/**
* 訪問決策 管理器 (自定義)
* @author admin
*
*/
@Service
public class SysAccessDecisionManager implements AccessDecisionManager{
/**
* 角色判斷
* authentication -- 角色的資訊
* object --路徑
* configAttributes -- 路徑需要的許可權
*/
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
if (configAttributes == null) {
return;
}
Iterator<ConfigAttribute> iterator = configAttributes.iterator();
while (iterator.hasNext()) {
ConfigAttribute configAttribute = iterator.next();
String needPermission = configAttribute.getAttribute();
for (GrantedAuthority ga : authentication.getAuthorities()) {
if (needPermission.equals(ga.getAuthority())) { //路徑需要的許可權和角色擁有的許可權比較
return;
}
}
}
// 沒有許可權讓我們去捕捉
throw new AccessDeniedException("您當前沒有許可權!");
}
@Override
public boolean supports(ConfigAttribute attribute) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}
}
3. 總結
以上就是資源的載入和認證