版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NameGGG/article/details/77143622
序言
这一篇主要是讲资源的加载和认证
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. 总结
以上就是资源的加载和认证