springBoot2.2.2+springsecurity+mybatis(三)动态配置权限,简单

本文详细介绍如何通过自定义CustomFilterInvocationSecurityMetadaSource和AccessDecisionManager来实现Spring Security的权限控制,包括角色信息的获取与对比,以及数据库设计与配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库设计
在这里插入图片描述在这里插入图片描述
2.自定义CustomFilterInvocationSecurityMetadaSource(获取角色信息)

@Component
public class CustomFilterInvocationSecurityMetadaSource implements FilterInvocationSecurityMetadataSource {
   AntPathMatcher antPathMatcher=new AntPathMatcher();//实现ant风格的URL匹配
    @Resource
    private MenuMapper menuMapper;
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) o).getRequestUrl();//当前请求路径
        List<Menu> allMenus = menuMapper.getAllMenus();
        //遍历资源信息
        for (Menu menu:
             allMenus) {
            //判断当前请求的URL在资源表中是否存在相应的模式,不存在则假设请求登录后即可访问
         if(antPathMatcher.match(menu.getPattern(),requestUrl)){
            List<Role> roles=menu.getRoles();
            String[] roleArr=new String[roles.size()];
             for (int i = 0; i <roleArr.length ; i++) {
                 roleArr[i]=roles.get(i).getName();
             }
             return SecurityConfig.createList(roleArr);
         }
        }
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    /**
     * 返回所有已经定义好的权限资源,spring security启动时会检验相关配置是否正确,不需检验,则返回null
     * @return
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }
    /**
     * 返回对象是否支持检验
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}

3.自定义AccessDecisionManager(对比角色信息)

    /**
     *
     * @param auth 当前登录用户的信息
     * @param o FilterInvocation对象,可获取当前请求对象
     * @param ca FilterInvocationSecurityMetadataSource中的getAttribute的返回值
     *           Collection<ConfigAttribute> 当前请求URL所需的角色
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    @Override
    public void decide(Authentication auth, Object o, Collection<ConfigAttribute> ca) throws AccessDeniedException, InsufficientAuthenticationException {
        /**
         * 判断当前登录的用户
         * 是否具有当前请求所需要的角色信息
         * 不具备,抛出AccessDeniedException异常,否则不需任何事即可
         */
        Collection<? extends GrantedAuthority> auths = auth.getAuthorities();
        for (ConfigAttribute configAttribute:
        ca) {
             if("ROLE_LOGIN".equals(configAttribute.getAttribute())
              && auth instanceof UsernamePasswordAuthenticationToken){
               return;
             }
             for (GrantedAuthority authority:auths){
                 if(configAttribute.getAttribute().equals(authority.getAuthority())){
                  return;
                 }
             }
        }
        throw  new AccessDeniedException("权限不足");
    }
    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
} 

4.mapper+xml

@Mapper
public interface MenuMapper {
     List<Menu> getAllMenus();
}

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.MenuMapper">
     <resultMap id="BaseResultMap" type="com.example.demo.pojo.Menu">
         <id property="id" column="id"/>
         <result property="pattern" column="pattern"/>
         <collection property="roles" ofType="com.example.demo.pojo.Role">
             <id property="id" column="rid"/>
             <result property="name" column="rname"/>
             <result property="nameZh" column="rnameZh"/>
         </collection>
     </resultMap>
     <select id="getAllMenus" resultMap="BaseResultMap">
      SELECT  m.*,
         r.id AS rid,
         r.name AS rname,
          r.nameZh AS rnameZh
             FROM menu m
      LEFT JOIN menu_role mr ON m.id=mr.mid
      LEFT JOIN role r  ON mr.`rid`=r.id
     </select>
</mapper>

5.配置类

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.withObjectPostProcessor(new ObjectPostProcessor() {
@Override
public O postProcess(O o) {
o.setSecurityMetadataSource(cfisms());
o.setAccessDecisionManager(cadm());
return o;
}
})
.and()
.formLogin()
.loginProcessingUrl("/login").permitAll()
.and()
.csrf().disable();
}
@Bean
CustomFilterInvocationSecurityMetadaSource cfisms(){
return new CustomFilterInvocationSecurityMetadaSource();
}

@Bean
CustomAccessDesisionManager cadm(){
    return new CustomAccessDesisionManager();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值