Spring security 动态权限管理(基于数据库)

打印 上一主题 下一主题

主题 755|帖子 755|积分 2265

一、简介

假如对该篇文章不了解,请移步上一篇文章:spring security 中的授权利用-CSDN博客
        当我们配置的 URL 拦截规则哀求 URL 所需要的权限都是通过代码来配置的,这样就比较死板,假如想要调解访问某一个 URL 所需要的权限,就需要修改代码。动态管理权限规则就是我们将UR 拦截规则和访问 URI 所需要的权限都生存在数据库中,这样,在不修改源代码的环境下,只需要修改数据库中的数据,就可以对权限举行调解。
  



二、库表设计

        里面涉及到 用户 ,角色 ,权限   ,用户角色关系表,角色菜单表共计五张表,用户是用来认证利用的;其中是一些建表语句,假如角色复杂可以将用户这会用内存实现;
  2.1 权限表

  1. -- 菜单表
  2. CREATE TABLE `t_authority_menu`(
  3.   id int(11) NOT NULL AUTO_INCREMENT primary key ,
  4.   pattern_url varchar(128) DEFAULT ''
  5. )ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  6. -- 添加数据
  7. BEGIN;
  8.   insert into t_authority_menu values (1,'/admin/**');
  9.   insert into t_authority_menu values (2,'/user/**');
  10.   insert into t_authority_menu values (3,'/guest/**');
  11. commit ;
复制代码
2.2 角色表

  1. -- 角色表
  2. CREATE TABLE `t_authority_role`(
  3.   id int(11) NOT NULL AUTO_INCREMENT primary key ,
  4.   role_name varchar(128) DEFAULT '' comment '角色标识',
  5.   role_desc varchar(128) DEFAULT '' comment '角色描述'
  6. )ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  7. -- 添加数据
  8. BEGIN;
  9. insert into t_authority_role values (1,'ROLE_ADMIN','系统管理员');
  10. insert into t_authority_role values (2,'ROLE_USER','普通用户');
  11. insert into t_authority_role values (3,'ROLE_GUEST','游客');
  12. commit ;
复制代码
2.3 角色权限关联表

  1. -- 角色菜单关系表 primary key (m_id,r_id)
  2. CREATE TABLE `t_authority_role_menu`(
  3.   id int(11) NOT NULL AUTO_INCREMENT primary key,
  4.   m_id int(11) DEFAULT NULL comment '菜单id',
  5.   r_id int(11) DEFAULT NULL comment '角色id'
  6. )ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  7. -- 创建唯一索引
  8. CREATE UNIQUE INDEX i_authority_role_menu1 ON t_authority_role_menu(m_id, r_id);
  9. -- 添加数据
  10. BEGIN;
  11. insert into t_authority_role_menu(m_id, r_id) values (1,1);
  12. insert into t_authority_role_menu(m_id, r_id) values (2,1);
  13. insert into t_authority_role_menu(m_id, r_id) values (2,2);
  14. insert into t_authority_role_menu(m_id, r_id) values (3,3);
  15. insert into t_authority_role_menu(m_id, r_id) values (3,2);
  16. commit ;
复制代码
2.4 用户表

  1. -- 用户表
  2. CREATE TABLE t_authority_user (
  3.   id int(11)  NOT NULL AUTO_INCREMENT primary key,
  4.   user_name   varchar(32) DEFAULT '' comment '用户名',
  5.   password    varchar(32) DEFAULT '' comment '密码',
  6.   enabled     tinyint(1) DEFAULT 1 comment '是否启用  1启用',
  7.   locked      tinyint(1) DEFAULT 1 comment '是否锁定  1 未锁定'
  8. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  9. BEGIN;
  10. insert into t_authority_user values (1,'admin','{noop}123456','1','1');
  11. insert into t_authority_user values (2,'user','{noop}123456','1','1');
  12. insert into t_authority_user values (3,'guest','{noop}123456','1','1');
  13. commit ;
复制代码
2.5 用户角色关联表

  1. -- 角色用户关系表
  2. CREATE TABLE `t_authority_role_user`(
  3.   id int(11) NOT NULL AUTO_INCREMENT primary key ,
  4.   u_id int(11) DEFAULT 0 comment '用户id',
  5.   r_id int(11) DEFAULT 0 comment '角色id'
  6. )ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  7. -- 创建唯一索引
  8. CREATE UNIQUE INDEX i_authority_role_user1 ON t_authority_role_user(u_id, r_id);
  9. -- 添加数据
  10. BEGIN;
  11. insert into t_authority_role_user(u_id, r_id) values (1,1);
  12. insert into t_authority_role_user(u_id, r_id) values (1,2);
  13. insert into t_authority_role_user(u_id, r_id) values (2,2);
  14. insert into t_authority_role_user(u_id, r_id) values (3,3);
  15. commit ;
复制代码








三、用户角色权限相关

   我们设计 用户 《=》角色  《=》 权限,一个用户拥有多个角色,一个角色对应多个权限
  3.1 相关实体类

  1. // 用户
  2. @Data
  3. public class AuthorityUser implements Serializable {
  4.     private Integer id;
  5.     /**
  6.      * 用户名
  7.      */
  8.     private String userName;
  9.     /**
  10.      * 密码
  11.      */
  12.     private String password;
  13.     /**
  14.      * 是否启用  1启用
  15.      */
  16.     private Boolean enabled;
  17.     /**
  18.      * 是否锁定  1 未锁定
  19.      */
  20.     private Boolean locked;
  21.     private static final long serialVersionUID = 1L;
  22. }
  23. // 角色
  24. @Data
  25. public class AuthorityRole implements Serializable {
  26.     private Integer id;
  27.     /**
  28.      * 角色标识
  29.      */
  30.     private String roleName;
  31.     /**
  32.      * 角色描述
  33.      */
  34.     private String roleDesc;
  35.     private static final long serialVersionUID = 1L;
  36. }
  37. // 菜单
  38. @Data
  39. public class AuthorityMenu implements Serializable {
  40.     private Integer id;
  41.     private String patternUrl;
  42.     /**
  43.      *  一个菜单对应多个角色
  44.      */
  45.     private List<AuthorityRole> roles;
  46.     private static final long serialVersionUID = 1L;
  47. }
复制代码


3.2 相关dao 接口

  1. // 用户dao
  2. public interface AuthorityUserDao {
  3.     /**
  4.      *  根据用户名获取用户信息  认证使用
  5.      * @param id
  6.      * @return
  7.      */
  8.     AuthorityUser selectByusername(String id);
  9.     int deleteByPrimaryKey(Integer id);
  10.     int insert(AuthorityUser record);
  11.     int insertSelective(AuthorityUser record);
  12.     AuthorityUser selectByPrimaryKey(Integer id);
  13.     int updateByPrimaryKeySelective(AuthorityUser record);
  14.     int updateByPrimaryKey(AuthorityUser record);
  15. }
  16. // 角色
  17. public interface AuthorityRoleDao {
  18.     /**
  19.      *  根据用户编码获取角色列表
  20.      * @param userId
  21.      * @return
  22.      */
  23.     List<AuthorityRole> selectRoleListByUserId(int userId);
  24.     int deleteByPrimaryKey(Integer id);
  25.     int insert(AuthorityRole record);
  26.     int insertSelective(AuthorityRole record);
  27.     AuthorityRole selectByPrimaryKey(Integer id);
  28.     int updateByPrimaryKeySelective(AuthorityRole record);
  29.     int updateByPrimaryKey(AuthorityRole record);
  30. }
  31. // 权限
  32. public interface AuthorityMenuDao {
  33.     AuthorityMenu selectByPrimaryKey(Integer id);
  34.     /**
  35.      *  获取所有的菜单权限
  36.      * @return
  37.      */
  38.     List<AuthorityMenu> getAllMenu();
  39. }
复制代码
3.3 dao对应的xml   mybatis

  1. // 用户
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.fashion.mapper.mysql.AuthorityUserDao">
  5.   <resultMap id="BaseResultMap" type="com.fashion.model.AuthorityUser">
  6.     <id column="id" jdbcType="INTEGER" property="id" />
  7.     <result column="user_name" jdbcType="VARCHAR" property="userName" />
  8.     <result column="password" jdbcType="VARCHAR" property="password" />
  9.     <result column="enabled" jdbcType="BOOLEAN" property="enabled" />
  10.     <result column="locked" jdbcType="BOOLEAN" property="locked" />
  11.   </resultMap>
  12.   <sql id="Base_Column_List">
  13.     id, user_name, `password`, enabled, locked
  14.   </sql>
  15.   <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
  16.     select
  17.     <include refid="Base_Column_List" />
  18.     from t_authority_user
  19.     where id = #{id,jdbcType=INTEGER}
  20.   </select>
  21.   <select id="selectByusername" parameterType="java.lang.String" resultMap="BaseResultMap">
  22.     select
  23.     <include refid="Base_Column_List" />
  24.     from t_authority_user
  25.     where user_name = #{userName}
  26.   </select>
  27.   <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
  28.     delete from t_authority_user
  29.     where id = #{id,jdbcType=INTEGER}
  30.   </delete>
  31.   <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.fashion.model.AuthorityUser" useGeneratedKeys="true">
  32.     insert into t_authority_user (user_name, `password`, enabled,
  33.       locked)
  34.     values (#{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{enabled,jdbcType=BOOLEAN},
  35.       #{locked,jdbcType=BOOLEAN})
  36.   </insert>
  37.   <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.fashion.model.AuthorityUser" useGeneratedKeys="true">
  38.     insert into t_authority_user
  39.     <trim prefix="(" suffix=")" suffixOverrides=",">
  40.       <if test="userName != null">
  41.         user_name,
  42.       </if>
  43.       <if test="password != null">
  44.         `password`,
  45.       </if>
  46.       <if test="enabled != null">
  47.         enabled,
  48.       </if>
  49.       <if test="locked != null">
  50.         locked,
  51.       </if>
  52.     </trim>
  53.     <trim prefix="values (" suffix=")" suffixOverrides=",">
  54.       <if test="userName != null">
  55.         #{userName,jdbcType=VARCHAR},
  56.       </if>
  57.       <if test="password != null">
  58.         #{password,jdbcType=VARCHAR},
  59.       </if>
  60.       <if test="enabled != null">
  61.         #{enabled,jdbcType=BOOLEAN},
  62.       </if>
  63.       <if test="locked != null">
  64.         #{locked,jdbcType=BOOLEAN},
  65.       </if>
  66.     </trim>
  67.   </insert>
  68.   <update id="updateByPrimaryKeySelective" parameterType="com.fashion.model.AuthorityUser">
  69.     update t_authority_user
  70.     <set>
  71.       <if test="userName != null">
  72.         user_name = #{userName,jdbcType=VARCHAR},
  73.       </if>
  74.       <if test="password != null">
  75.         `password` = #{password,jdbcType=VARCHAR},
  76.       </if>
  77.       <if test="enabled != null">
  78.         enabled = #{enabled,jdbcType=BOOLEAN},
  79.       </if>
  80.       <if test="locked != null">
  81.         locked = #{locked,jdbcType=BOOLEAN},
  82.       </if>
  83.     </set>
  84.     where id = #{id,jdbcType=INTEGER}
  85.   </update>
  86.   <update id="updateByPrimaryKey" parameterType="com.fashion.model.AuthorityUser">
  87.     update t_authority_user
  88.     set user_name = #{userName,jdbcType=VARCHAR},
  89.       `password` = #{password,jdbcType=VARCHAR},
  90.       enabled = #{enabled,jdbcType=BOOLEAN},
  91.       locked = #{locked,jdbcType=BOOLEAN}
  92.     where id = #{id,jdbcType=INTEGER}
  93.   </update>
  94. </mapper>
  95. // 角色
  96. <?xml version="1.0" encoding="UTF-8"?>
  97. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  98. <mapper namespace="com.fashion.mapper.mysql.AuthorityRoleDao">
  99.   <resultMap id="BaseResultMap" type="com.fashion.model.AuthorityRole">
  100.     <id column="id" jdbcType="INTEGER" property="id" />
  101.     <result column="role_name" jdbcType="VARCHAR" property="roleName" />
  102.     <result column="role_desc" jdbcType="VARCHAR" property="roleDesc" />
  103.   </resultMap>
  104.   <sql id="Base_Column_List">
  105.     id, role_name, role_desc
  106.   </sql>
  107.   <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
  108.     select
  109.     <include refid="Base_Column_List" />
  110.     from t_authority_role
  111.     where id = #{id,jdbcType=INTEGER}
  112.   </select>
  113.   <select id="selectRoleListByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
  114.     select a.role_name,a.role_desc from
  115.      t_authority_role a
  116.      left join t_authority_role_user b on a.id = b.r_id
  117.       where b.u_id = #{userId}
  118.   </select>
  119.   <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
  120.     delete from t_authority_role
  121.     where id = #{id,jdbcType=INTEGER}
  122.   </delete>
  123.   <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.fashion.model.AuthorityRole" useGeneratedKeys="true">
  124.     insert into t_authority_role (role_name, role_desc)
  125.     values (#{roleName,jdbcType=VARCHAR}, #{roleDesc,jdbcType=VARCHAR})
  126.   </insert>
  127.   <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.fashion.model.AuthorityRole" useGeneratedKeys="true">
  128.     insert into t_authority_role
  129.     <trim prefix="(" suffix=")" suffixOverrides=",">
  130.       <if test="roleName != null">
  131.         role_name,
  132.       </if>
  133.       <if test="roleDesc != null">
  134.         role_desc,
  135.       </if>
  136.     </trim>
  137.     <trim prefix="values (" suffix=")" suffixOverrides=",">
  138.       <if test="roleName != null">
  139.         #{roleName,jdbcType=VARCHAR},
  140.       </if>
  141.       <if test="roleDesc != null">
  142.         #{roleDesc,jdbcType=VARCHAR},
  143.       </if>
  144.     </trim>
  145.   </insert>
  146.   <update id="updateByPrimaryKeySelective" parameterType="com.fashion.model.AuthorityRole">
  147.     update t_authority_role
  148.     <set>
  149.       <if test="roleName != null">
  150.         role_name = #{roleName,jdbcType=VARCHAR},
  151.       </if>
  152.       <if test="roleDesc != null">
  153.         role_desc = #{roleDesc,jdbcType=VARCHAR},
  154.       </if>
  155.     </set>
  156.     where id = #{id,jdbcType=INTEGER}
  157.   </update>
  158.   <update id="updateByPrimaryKey" parameterType="com.fashion.model.AuthorityRole">
  159.     update t_authority_role
  160.     set role_name = #{roleName,jdbcType=VARCHAR},
  161.       role_desc = #{roleDesc,jdbcType=VARCHAR}
  162.     where id = #{id,jdbcType=INTEGER}
  163.   </update>
  164. </mapper>
  165. // 菜单
  166. <?xml version="1.0" encoding="UTF-8"?>
  167. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  168. <mapper namespace="com.fashion.mapper.mysql.AuthorityMenuDao">
  169.   <resultMap id="BaseResultMap" type="com.fashion.model.AuthorityMenu">
  170.     <id column="id" jdbcType="INTEGER" property="id" />
  171.     <result column="pattern_url" jdbcType="VARCHAR" property="patternUrl" />
  172.   </resultMap>
  173.   <sql id="Base_Column_List">
  174.     id, pattern_url
  175.   </sql>
  176.   <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
  177.     select
  178.     <include refid="Base_Column_List" />
  179.     from t_authority_menu
  180.     where id = #{id,jdbcType=INTEGER}
  181.   </select>
  182.   <resultMap id="MenuResultMap" type="com.fashion.model.AuthorityMenu">
  183.     <id column="id" jdbcType="INTEGER" property="id" />
  184.     <result column="pattern_url" jdbcType="VARCHAR" property="patternUrl" />
  185.     <collection property="roles" ofType="com.fashion.model.AuthorityRole">
  186.       <id column="rId" property="id"/>
  187.       <result column="role_name" jdbcType="VARCHAR" property="roleName" />
  188.       <result column="role_desc" jdbcType="VARCHAR" property="roleDesc" />
  189.     </collection>
  190. </resultMap>
  191.   <select id="getAllMenu"  resultMap="MenuResultMap">
  192.    select a.*,c.id rId,c.role_name,c.role_desc
  193.     from t_authority_menu a
  194.     left join t_authority_role_menu b on a.id = b.m_id
  195.     left join t_authority_role c on c.id = b.r_id
  196.   </select>
  197. </mapper>
复制代码




四、自界说UserDetailsService

   用来实现自界说登录逻辑,查询数据库用户,假如不懂请看前面系列教程
  1. @Service
  2. public class UserServiceDetailImpl implements UserDetailsService {
  3.     @Autowired
  4.     private AuthorityUserDao authorityUserDao;
  5.     @Autowired
  6.     private AuthorityRoleDao authorityRoleDao;
  7.     /**
  8.      *  认证
  9.      * @param username
  10.      * @return
  11.      * @throws UsernameNotFoundException
  12.      */
  13.     @Override
  14.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  15.         // 1、 根据用户名获取信息
  16.         AuthorityUser authorityUser = authorityUserDao.selectByusername(username);
  17.         if (null == authorityUser) {
  18.             throw new UsernameNotFoundException("用户不存在!");
  19.         }
  20.         // 2、获取用户对应的角色
  21.         List<AuthorityRole> roles = authorityRoleDao.selectRoleListByUserId(authorityUser.getId());
  22.         UserDetailInf userDetailInf = new UserDetailInf(authorityUser, roles);
  23.         return userDetailInf;
  24.     }
  25. }
复制代码
4.1  UserDetails 自界说

   用来生存用户登录成功后,SpringSecurityHolder中的认证信息,里面有用户权限信息
  1. public class UserDetailInf implements UserDetails {
  2.     private AuthorityUser user;
  3.     private List<AuthorityRole> roles;
  4.     public UserDetailInf(AuthorityUser user, List<AuthorityRole> roles) {
  5.         this.user = user;
  6.         this.roles = roles;
  7.     }
  8.     @Override
  9.     public Collection<? extends GrantedAuthority> getAuthorities() {
  10.         return roles.stream()
  11.                 .map(r -> new SimpleGrantedAuthority(r.getRoleName()))
  12.                 .collect(ArrayList::new, List::add,List::addAll);
  13.     }
  14.     @Override
  15.     public String getPassword() {
  16.         return user.getPassword();
  17.     }
  18.     @Override
  19.     public String getUsername() {
  20.         return user.getPassword();
  21.     }
  22.     @Override
  23.     public boolean isAccountNonExpired() {
  24.         return true;
  25.     }
  26.     @Override
  27.     public boolean isAccountNonLocked() {
  28.         return true;
  29.     }
  30.     @Override
  31.     public boolean isCredentialsNonExpired() {
  32.         return true;
  33.     }
  34.     @Override
  35.     public boolean isEnabled() {
  36.         return true;
  37.     }
  38. }
复制代码
4.2 自界说数据源扫码mapper

  1. @Configuration
  2. @MapperScan(basePackages = MysqlDsConfiguration.PACKAGE, sqlSessionFactoryRef = "mysqlSqlSessionFactory" )
  3. @Slf4j
  4. public class MysqlDsConfiguration {
  5.     static final String PACKAGE = "com.fashion.mapper.mysql";
  6.     static final String MAPPER_LOCATION = "classpath:mybatis/mapper/mysql/*.xml";
  7.     /**
  8.      *  配置数据源
  9.      * @return
  10.      */
  11.     @Primary
  12.     @Bean
  13.     public DataSource mysqlDataSource(){
  14.         DruidDataSource dataSource = new DruidDataSource();
  15.         dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
  16.         dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
  17.         dataSource.setUsername("root");
  18.         dataSource.setPassword("12345");
  19.         return dataSource;
  20.     }
  21.     @Primary
  22.     @Bean
  23.     public SqlSessionFactory mysqlSqlSessionFactory(@Autowired DataSource mysqlDataSource){
  24.         SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  25.         try {
  26.             sessionFactory.setDataSource(mysqlDataSource);
  27.             sessionFactory.setConfigLocation(new ClassPathResource("/mybatis/mybatis-config.xml"));
  28.             sessionFactory.setMapperLocations(
  29.                     new PathMatchingResourcePatternResolver().getResources(MysqlDsConfiguration.MAPPER_LOCATION));
  30.             return sessionFactory.getObject();
  31.         } catch (Exception e) {
  32.             log.error("mysql数据源初始化失败",e);
  33.         }
  34.         return null;
  35.     }
  36. }
复制代码




五、界说 MetadataSource 权限信息

       实现 FilterInvocationSecurity ,用来将权限对应的角色信息加载进去,该类用于我们重写getAttributes ,将我们菜单对应的角色权限查询出来,实现动态授权
  1. @Component
  2. public class UrlAntPatchMetadataSource implements FilterInvocationSecurityMetadataSource {
  3.     @Autowired
  4.     private AuthorityMenuDao authorityMenuDao;
  5.     private AntPathMatcher antPathMatcher = new AntPathMatcher();
  6.     @Override
  7.     public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
  8.         // 当前obj 实际上是一个url
  9.         String requestURI = ((FilterInvocation) object).getRequest().getRequestURI();
  10.         // 获取所有的url 对应的角色集合
  11.         List<AuthorityMenu> allAuthorityMenus = authorityMenuDao.getAllMenu();
  12.         String[] roles = allAuthorityMenus.stream()
  13.                 .filter(menu -> antPathMatcher.match(menu.getPatternUrl(),requestURI))
  14.                 .flatMap(authorityMenu -> authorityMenu.getRoles().stream())
  15.                 .map(AuthorityRole::getRoleName)
  16.                 .toArray(String[]::new);
  17.         if (null != roles && roles.length > 0) {
  18.             return SecurityConfig.createList(roles);
  19.         }
  20. //        for (AuthorityMenu menu : allAuthorityMenus) {
  21. //            if (antPathMatcher.match(menu.getPatternUrl(),requestURI)) {
  22. //                String[] roles = menu.getRoles().stream().map(r -> r.getRoleName()).toArray(String[]::new);
  23. //                return SecurityConfig.createList(roles);
  24. //            }
  25. //        }
  26.         return null;
  27.     }
  28.     @Override
  29.     public Collection<ConfigAttribute> getAllConfigAttributes() {
  30.         return null;
  31.     }
  32.     @Override
  33.     public boolean supports(Class<?> clazz) {
  34.         return FilterInvocation.class.isAssignableFrom(clazz);
  35.     }
  36. }
复制代码


六、SecurityConfiguration 配置

   
  1、设置全局的自界说数据源
2、设置权限过滤规则,将自界说的FilterInvocationSecurityMetadataSource注入
  1. @Configuration
  2. @EnableGlobalMethodSecurity(prePostEnabled = true)
  3. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  4.     @Autowired
  5.     private UserDetailsService userDetailsService;
  6.     @Autowired
  7.     private UrlAntPatchMetadataSource urlAntPatchMetadataSource;
  8.     @Override
  9.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  10.         auth.userDetailsService(userDetailsService);
  11.     }
  12.     @Override
  13.     protected void configure(HttpSecurity http) throws Exception {
  14.         // 1、获取工厂对象
  15.         ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
  16.         // 2、设置自定义url 匹配规则
  17.         http.apply(new UrlAuthorizationConfigurer<>(applicationContext))
  18.              .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
  19.                  @Override
  20.                  public <O extends FilterSecurityInterceptor> O postProcess(O object) {
  21.                      object.setSecurityMetadataSource(urlAntPatchMetadataSource);
  22.                      // 如果没有权限是否拒绝
  23.                      object.setRejectPublicInvocations(true);
  24.                      return object;
  25.                  }
  26.              });
  27.         http.authorizeRequests()
  28.                 .anyRequest().authenticated()
  29.                 .and().formLogin()//开启表单登录
  30.                 .and().csrf().disable();
  31.     }
  32. }
复制代码



七、测试controller

   用户对应的角色分析
          admin 用户拥有 ROLE_ADMIN/ROLE_USER 的角色
          user 用户拥有  ROLE_USER 的角色
          guest 用户拥有  ROLE_GUEST 的角色
  
  角色对应的权限分析
          ROLE_ADMIN角色拥有 /admin/** 以及 /user/** 以下权限
          ROLE_USER 角色拥有 /user/** 以及/guest/**  以下权限
          ROLE_GUEST用户拥有 /guest/** 路径以下权限
  1. @RestController
  2. public class HelloController {
  3.     /**
  4.      *
  5.      * @return
  6.      */
  7.     @RequestMapping("/admin/hello")
  8.     public String admin() {
  9.         return "hello admin";
  10.     }
  11.     @RequestMapping("/user/hello")
  12.     public String user() {
  13.         return "hello user";
  14.     }
  15.     @RequestMapping("/guest/hello")
  16.     public String guest() {
  17.         return "hello guest";
  18.     }
  19.     @RequestMapping("/hello")
  20.     public String hello() {
  21.         return "hello";
  22.     }
  23. }
复制代码
7.1  admin 登录测试效果

   利用 admin 用户登录,我们访问接口测试权限,经分析,admin 拥有下面全部的权限,对应controller中的三个方法是都可以访问的;
  





7.2 user登录测试效果

   利用 user用户登录,分析得到;user用户只能访问 /user/hello  或者 /guest/hello 接口
  





7.3 guest 用户登录测试效果

   利用 guest用户登录,分析得到;guest用户只能访问 /guest/hello 接口
  





八、题目总结

   
  一、AntPathMatcher中的mather 方法,里面千万不能写反了,第一个是我们通配库里面界说的,第二个参数为哀求的url,两个的次序不能对调;
antPathMatcher.match(menu.getPatternUrl(),requestURI)  
  
  二、我们每一次授权都需要走一次数据库,性能题目;
   办理方案:
         1、设置一个hutool中的timecache 定时扫除里面对应权限信息,设置10分钟,这样我们10分钟才跟数据源有一次交互;题目就是集群,大概每一台里面都需要放一次,优点是服从更高
        2、我们将权限信息存到redis中,这种方案更好,假如是集群也不影响;缺点就是需要一个redis的依赖;
  
源码跟文档我都上传了,有需求的小伙伴自行下载,下载链接:
https://download.csdn.net/download/qq_36260963/89733771



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表