Spring Security 4 (03)—— 资源信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 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. 总结

以上就是资源的加载和认证

猜你喜欢

转载自blog.csdn.net/NameGGG/article/details/77143622
今日推荐