经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
详解如何在项目中应用SpringSecurity权限控制
来源:jb51  时间:2022/6/27 9:03:20  对本文有异议

要进行认证和授权需要前面课程中提到的权限模型涉及的7张表支撑,因为用户信息、权限信息、菜单信息、角色信息、关联信息等都保存在这7张表中,也就是这些表中的数据是我们进行认证和授权的依据。所以在真正进行认证和授权之前需要对这些数据进行管理,即我们需要开发如下一些功能:

1、权限数据管理(增删改查)

2、菜单数据管理(增删改查)

3、角色数据管理(增删改查、角色关联权限、角色关联菜单)

4、用户数据管理(增删改查、用户关联角色)

数据库数据实现导入,简化上面的4步步骤

  1. DROP TABLE IF EXISTS `t_user`;
  2. CREATE TABLE `t_user` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `birthday` date DEFAULT NULL,
  5. `gender` varchar(1) DEFAULT NULL,
  6. `username` varchar(32) DEFAULT NULL,
  7. `password` varchar(256) DEFAULT NULL,
  8. `remark` varchar(32) DEFAULT NULL,
  9. `station` varchar(1) DEFAULT NULL,
  10. `telephone` varchar(11) DEFAULT NULL,
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  13.  
  14. -- ----------------------------
  15. -- Records of t_user
  16. -- ----------------------------
  17. INSERT INTO `t_user` VALUES ('1', null, null, 'admin', '$2a$10$u/BcsUUqZNWUxdmDhbnoeeobJy6IBsL1Gn/S0dMxI2RbSgnMKJ.4a', null, null, null);
  18. INSERT INTO `t_user` VALUES ('2', null, null, 'xiaoming', '$2a$10$3xW2nBjwBM3rx1LoYprVsemNri5bvxeOd/QfmO7UDFQhW2HRHLi.C', null, null, null);
  19. INSERT INTO `t_user` VALUES ('3', null, null, 'test', '$2a$10$zYJRscVUgHX1wqwu90WereuTmIg6h/JGirGG4SWBsZ60wVPCgtF8W', null, null, null);
  20.  
  21. DROP TABLE IF EXISTS `t_user_role`;
  22. CREATE TABLE `t_user_role` (
  23. `user_id` int(11) NOT NULL,
  24. `role_id` int(11) NOT NULL,
  25. PRIMARY KEY (`user_id`,`role_id`),
  26. KEY `FK_Reference_8` (`role_id`),
  27. CONSTRAINT `FK_Reference_7` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`),
  28. CONSTRAINT `FK_Reference_8` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)
  29. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  30.  
  31. -- ----------------------------
  32. -- Records of t_user_role
  33. -- ----------------------------
  34. INSERT INTO `t_user_role` VALUES ('1', '1');
  35. INSERT INTO `t_user_role` VALUES ('2', '2');
  36.  
  37. DROP TABLE IF EXISTS `t_permission`;
  38. CREATE TABLE `t_permission` (
  39. `id` int(11) NOT NULL AUTO_INCREMENT,
  40. `name` varchar(32) DEFAULT NULL,
  41. `keyword` varchar(64) DEFAULT NULL,
  42. `description` varchar(128) DEFAULT NULL,
  43. PRIMARY KEY (`id`)
  44. ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
  45.  
  46. -- ----------------------------
  47. -- Records of t_permission
  48. -- ----------------------------
  49. INSERT INTO `t_permission` VALUES ('1', '新增检查项', 'CHECKITEM_ADD', null);
  50. INSERT INTO `t_permission` VALUES ('2', '删除检查项', 'CHECKITEM_DELETE', null);
  51. INSERT INTO `t_permission` VALUES ('3', '编辑检查项', 'CHECKITEM_EDIT', null);
  52. INSERT INTO `t_permission` VALUES ('4', '查询检查项', 'CHECKITEM_QUERY', null);
  53. INSERT INTO `t_permission` VALUES ('5', '新增检查组', 'CHECKGROUP_ADD', null);
  54. INSERT INTO `t_permission` VALUES ('6', '删除检查组', 'CHECKGROUP_DELETE', null);
  55. INSERT INTO `t_permission` VALUES ('7', '编辑检查组', 'CHECKGROUP_EDIT', null);
  56. INSERT INTO `t_permission` VALUES ('8', '查询检查组', 'CHECKGROUP_QUERY', null);
  57. INSERT INTO `t_permission` VALUES ('9', '新增套餐', 'SETMEAL_ADD', null);
  58. INSERT INTO `t_permission` VALUES ('10', '删除套餐', 'SETMEAL_DELETE', null);
  59. INSERT INTO `t_permission` VALUES ('11', '编辑套餐', 'SETMEAL_EDIT', null);
  60. INSERT INTO `t_permission` VALUES ('12', '查询套餐', 'SETMEAL_QUERY', null);
  61. INSERT INTO `t_permission` VALUES ('13', '预约设置', 'ORDERSETTING', null);
  62. INSERT INTO `t_permission` VALUES ('14', '查看统计报表', 'REPORT_VIEW', null);
  63. INSERT INTO `t_permission` VALUES ('15', '新增菜单', 'MENU_ADD', null);
  64. INSERT INTO `t_permission` VALUES ('16', '删除菜单', 'MENU_DELETE', null);
  65. INSERT INTO `t_permission` VALUES ('17', '编辑菜单', 'MENU_EDIT', null);
  66. INSERT INTO `t_permission` VALUES ('18', '查询菜单', 'MENU_QUERY', null);
  67. INSERT INTO `t_permission` VALUES ('19', '新增角色', 'ROLE_ADD', null);
  68. INSERT INTO `t_permission` VALUES ('20', '删除角色', 'ROLE_DELETE', null);
  69. INSERT INTO `t_permission` VALUES ('21', '编辑角色', 'ROLE_EDIT', null);
  70. INSERT INTO `t_permission` VALUES ('22', '查询角色', 'ROLE_QUERY', null);
  71. INSERT INTO `t_permission` VALUES ('23', '新增用户', 'USER_ADD', null);
  72. INSERT INTO `t_permission` VALUES ('24', '删除用户', 'USER_DELETE', null);
  73. INSERT INTO `t_permission` VALUES ('25', '编辑用户', 'USER_EDIT', null);
  74. INSERT INTO `t_permission` VALUES ('26', '查询用户', 'USER_QUERY', null);
  75.  
  76. -- ----------------------------
  77. -- Table structure for `t_role`
  78. -- ----------------------------
  79. DROP TABLE IF EXISTS `t_role`;
  80. CREATE TABLE `t_role` (
  81. `id` int(11) NOT NULL AUTO_INCREMENT,
  82. `name` varchar(32) DEFAULT NULL,
  83. `keyword` varchar(64) DEFAULT NULL,
  84. `description` varchar(128) DEFAULT NULL,
  85. PRIMARY KEY (`id`)
  86. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
  87.  
  88. -- ----------------------------
  89. -- Records of t_role
  90. -- ----------------------------
  91. INSERT INTO `t_role` VALUES ('1', '系统管理员', 'ROLE_ADMIN', null);
  92. INSERT INTO `t_role` VALUES ('2', '健康管理师', 'ROLE_HEALTH_MANAGER', null);
  93.  
  94. -- ----------------------------
  95. -- Table structure for `t_role_menu`
  96. -- ----------------------------
  97. DROP TABLE IF EXISTS `t_role_menu`;
  98. CREATE TABLE `t_role_menu` (
  99. `role_id` int(11) NOT NULL,
  100. `menu_id` int(11) NOT NULL,
  101. PRIMARY KEY (`role_id`,`menu_id`),
  102. KEY `FK_Reference_10` (`menu_id`),
  103. CONSTRAINT `FK_Reference_10` FOREIGN KEY (`menu_id`) REFERENCES `t_menu` (`id`),
  104. CONSTRAINT `FK_Reference_9` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)
  105. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  106.  
  107. -- ----------------------------
  108. -- Records of t_role_menu
  109. -- ----------------------------
  110. INSERT INTO `t_role_menu` VALUES ('1', '1');
  111. INSERT INTO `t_role_menu` VALUES ('2', '1');
  112. INSERT INTO `t_role_menu` VALUES ('1', '2');
  113. INSERT INTO `t_role_menu` VALUES ('2', '2');
  114. INSERT INTO `t_role_menu` VALUES ('1', '3');
  115. INSERT INTO `t_role_menu` VALUES ('2', '3');
  116. INSERT INTO `t_role_menu` VALUES ('1', '4');
  117. INSERT INTO `t_role_menu` VALUES ('2', '4');
  118. INSERT INTO `t_role_menu` VALUES ('1', '5');
  119. INSERT INTO `t_role_menu` VALUES ('1', '6');
  120. INSERT INTO `t_role_menu` VALUES ('1', '7');
  121. INSERT INTO `t_role_menu` VALUES ('1', '8');
  122. INSERT INTO `t_role_menu` VALUES ('1', '9');
  123. INSERT INTO `t_role_menu` VALUES ('1', '10');
  124. INSERT INTO `t_role_menu` VALUES ('1', '11');
  125. INSERT INTO `t_role_menu` VALUES ('1', '12');
  126. INSERT INTO `t_role_menu` VALUES ('1', '13');
  127. INSERT INTO `t_role_menu` VALUES ('1', '14');
  128. INSERT INTO `t_role_menu` VALUES ('1', '15');
  129. INSERT INTO `t_role_menu` VALUES ('1', '16');
  130. INSERT INTO `t_role_menu` VALUES ('1', '17');
  131. INSERT INTO `t_role_menu` VALUES ('1', '18');
  132. INSERT INTO `t_role_menu` VALUES ('1', '19');
  133. INSERT INTO `t_role_menu` VALUES ('1', '20');
  134. INSERT INTO `t_role_menu` VALUES ('1', '21');
  135.  
  136. -- ----------------------------
  137. -- Table structure for `t_role_permission`
  138. -- ----------------------------
  139. DROP TABLE IF EXISTS `t_role_permission`;
  140. CREATE TABLE `t_role_permission` (
  141. `role_id` int(11) NOT NULL,
  142. `permission_id` int(11) NOT NULL,
  143. PRIMARY KEY (`role_id`,`permission_id`),
  144. KEY `FK_Reference_12` (`permission_id`),
  145. CONSTRAINT `FK_Reference_11` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`),
  146. CONSTRAINT `FK_Reference_12` FOREIGN KEY (`permission_id`) REFERENCES `t_permission` (`id`)
  147. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  148.  
  149. -- ----------------------------
  150. -- Records of t_role_permission
  151. -- ----------------------------
  152. INSERT INTO `t_role_permission` VALUES ('1', '1');
  153. INSERT INTO `t_role_permission` VALUES ('2', '1');
  154. INSERT INTO `t_role_permission` VALUES ('1', '2');
  155. INSERT INTO `t_role_permission` VALUES ('2', '2');
  156. INSERT INTO `t_role_permission` VALUES ('1', '3');
  157. INSERT INTO `t_role_permission` VALUES ('2', '3');
  158. INSERT INTO `t_role_permission` VALUES ('1', '4');
  159. INSERT INTO `t_role_permission` VALUES ('2', '4');
  160. INSERT INTO `t_role_permission` VALUES ('1', '5');
  161. INSERT INTO `t_role_permission` VALUES ('2', '5');
  162. INSERT INTO `t_role_permission` VALUES ('1', '6');
  163. INSERT INTO `t_role_permission` VALUES ('2', '6');
  164. INSERT INTO `t_role_permission` VALUES ('1', '7');
  165. INSERT INTO `t_role_permission` VALUES ('2', '7');
  166. INSERT INTO `t_role_permission` VALUES ('1', '8');
  167. INSERT INTO `t_role_permission` VALUES ('2', '8');
  168. INSERT INTO `t_role_permission` VALUES ('1', '9');
  169. INSERT INTO `t_role_permission` VALUES ('2', '9');
  170. INSERT INTO `t_role_permission` VALUES ('1', '10');
  171. INSERT INTO `t_role_permission` VALUES ('2', '10');
  172. INSERT INTO `t_role_permission` VALUES ('1', '11');
  173. INSERT INTO `t_role_permission` VALUES ('2', '11');
  174. INSERT INTO `t_role_permission` VALUES ('1', '12');
  175. INSERT INTO `t_role_permission` VALUES ('2', '12');
  176. INSERT INTO `t_role_permission` VALUES ('1', '13');
  177. INSERT INTO `t_role_permission` VALUES ('2', '13');
  178. INSERT INTO `t_role_permission` VALUES ('1', '14');
  179. INSERT INTO `t_role_permission` VALUES ('2', '14');
  180. INSERT INTO `t_role_permission` VALUES ('1', '15');
  181. INSERT INTO `t_role_permission` VALUES ('1', '16');
  182. INSERT INTO `t_role_permission` VALUES ('1', '17');
  183. INSERT INTO `t_role_permission` VALUES ('1', '18');
  184. INSERT INTO `t_role_permission` VALUES ('1', '19');
  185. INSERT INTO `t_role_permission` VALUES ('1', '20');
  186. INSERT INTO `t_role_permission` VALUES ('1', '21');
  187. INSERT INTO `t_role_permission` VALUES ('1', '22');
  188. INSERT INTO `t_role_permission` VALUES ('1', '23');
  189. INSERT INTO `t_role_permission` VALUES ('1', '24');
  190. INSERT INTO `t_role_permission` VALUES ('1', '25');
  191. INSERT INTO `t_role_permission` VALUES ('1', '26');

1、Spring Security环境准备

pom.xml中导入Spring Security的maven坐标,目前版本使用的是5.0.5.RELEASE,版本如果过高可能就会导致不同的报错

  1. <dependency>
  2. <groupId>org.springframework.security</groupId>
  3. <artifactId>spring-security-web</artifactId>
  4. <version>${spring.security.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.security</groupId>
  8. <artifactId>spring-security-config</artifactId>
  9. <version>${spring.security.version}</version>
  10. </dependency>

1.1、在health_backend工程的web.xml文件中配置用于整合Spring Security框架的过滤器DelegatingFilterProxy

  1. <!--委派过滤器,用于整合其他框架-->
  2. <filter>
  3. <!--整合spring security时,此过滤器的名称固定springSecurityFilterChain-->
  4. <filter-name>springSecurityFilterChain</filter-name>
  5. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  6. </filter>
  7. <!--注意区分放置的位置,有严格的先后顺序-->
  8. <filter-mapping>
  9. <filter-name>springSecurityFilterChain</filter-name>
  10. <url-pattern>/*</url-pattern>
  11. </filter-mapping>

2、实现认证和授权

在health_backend工程中按照Spring Security框架要求提供SpringSecurityUserService,并且实现UserDetailsService接口

  1. package com.zcl.security;
  2.  
  3. import com.alibaba.dubbo.config.annotation.Reference;
  4. import com.itheima.pojo.Permission;
  5. import com.itheima.pojo.Role;
  6. import com.itheima.pojo.User;
  7. import com.zcl.service.UserService;
  8. import org.springframework.security.core.GrantedAuthority;
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  10. import org.springframework.security.core.userdetails.UserDetails;
  11. import org.springframework.security.core.userdetails.UserDetailsService;
  12. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  13. import org.springframework.stereotype.Component;
  14.  
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.Set;
  18.  
  19. /**
  20. * 项目名称:health_parent
  21. * 描述:SpringSecurity实现认证和授权
  22. *
  23. * @author zhong
  24. * @date 2022-06-24 12:09
  25. */
  26. @Component
  27. public class SpringSecurityUserService implements UserDetailsService {
  28.  
  29. /**
  30. * 使用dubbo网络远程调用服务提供方查询用户数据
  31. */
  32. @Reference
  33. private UserService userService;
  34.  
  35. /**
  36. * 根据用户名查询数据库获取用户信息
  37. * @param username
  38. * @return
  39. * @throws UsernameNotFoundException
  40. */
  41. @Override
  42. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  43. User user = userService.findByUsername(username);
  44. if(user == null) {return null;};
  45. List<GrantedAuthority> list = new ArrayList<>();
  46. // 动态为当前用户授权
  47. Set<Role> roles = user.getRoles();
  48. // 遍历角色集合,为用户授予角色
  49. for (Role role : roles) {
  50. // 为用户授予角色
  51. list.add(new SimpleGrantedAuthority(role.getKeyword()));
  52. // 获取权限
  53. Set<Permission> permissions = role.getPermissions();
  54. // 遍历权限,为角色授权
  55. for (Permission permission : permissions) {
  56. list.add(new SimpleGrantedAuthority(permission.getKeyword()));
  57. }
  58. }
  59.  
  60. /*
  61. * 将密码交由框架比对
  62. * 参数一:账号
  63. * 参数二:查询数据库的密码,已加密的
  64. * 参数三:用户角色所具有的权限
  65. */
  66. org.springframework.security.core.userdetails.User UserSecurity = new org.springframework.security.core.userdetails.User(username,user.getPassword(),list);
  67. return UserSecurity;
  68. }
  69. }
  70.  

创建远程调用的UserService接口

  1. public interface UserService {
  2. /**
  3. * 根据登录名查询用户数据
  4. * @param username
  5. * @return
  6. */
  7. User findByUsername(String username);
  8. }

创建接口实现类

需要注入数据访问层来完成数据的查询,用户、角色、权限各自创建一个dao和映射文件

  1. package com.zcl.service.impl;
  2.  
  3. import com.alibaba.dubbo.config.annotation.Service;
  4. import com.itheima.pojo.Permission;
  5. import com.itheima.pojo.Role;
  6. import com.itheima.pojo.User;
  7. import com.zcl.dao.PermissionDao;
  8. import com.zcl.dao.RoleDao;
  9. import com.zcl.dao.UserDao;
  10. import com.zcl.service.UserService;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.transaction.annotation.Transactional;
  13.  
  14. import java.util.Set;
  15.  
  16. /**
  17. * 项目名称:health_parent
  18. * 描述:用户服务实现类
  19. *
  20. * @author zhong
  21. * @date 2022-06-24 14:35
  22. */
  23. @Service(interfaceClass = UserService.class)
  24. @Transactional
  25. public class UserServiceImpl implements UserService {
  26.  
  27. @Autowired
  28. private UserDao userDao;
  29.  
  30. @Autowired
  31. private RoleDao roleDao;
  32.  
  33. @Autowired
  34. private PermissionDao permissionDao;
  35.  
  36. /**
  37. * 根据用户名称查询用户角色信息和关联的角色信息,同时需要查询角色关联的权限信息
  38. * @param username
  39. * @return
  40. */
  41. @Override
  42. public User findByUsername(String username) {
  43. // 1、查询用户基本信息,不包含用户角色信息
  44. User user = userDao.findByUsername(username);
  45. if(user == null){
  46. return null;
  47. }
  48. // 2、根据用户查询的用户id查询角色信息
  49. Integer userId = user.getId();
  50. Set<Role> roles = roleDao.findByUserId(userId);
  51. // 3、根据角色来查询权限
  52. for (Role role : roles) {
  53. Integer roleId = role.getId();
  54. Set<Permission> permissions = permissionDao.findByRoleId(roleId);
  55. // 让角色关联权限
  56. role.setPermissions(permissions);
  57. }
  58. // 让用还关联角色
  59. user.setRoles(roles);
  60. return user;
  61. }
  62. }
  63.  

创建【用户、角色、权限】数据访问层接口

注意:这三个接口都不是在同一个类中的,而是各自独立的接口类,不要写在一起

  1. public interface UserDao {
  2. User findByUsername(String username);
  3. }
  4.  
  5. public interface RoleDao {
  6. Set<Role> findByUserId(Integer userId);
  7. }
  8.  
  9. public interface PermissionDao {
  10. Set<Permission> findByRoleId(Integer roleId);
  11. }

查询用户的Mapper映射文件查询数据

映射文件创建在resources文件下,注意的是需要与dao接口的包一致

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.zcl.dao.UserDao">
  6. <!--根据用户名称查询用户信息-->
  7. <select id="findByUsername" parameterType="string" resultType="com.itheima.pojo.User">
  8. select *
  9. from t_user
  10. where username = #{username}
  11. </select>
  12. </mapper>

根据用户id查询角色信息Mapper映射文件查询

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.zcl.dao.RoleDao">
  6. <!--根据用户id查询角色信息-->
  7. <select id="findByUserId" resultType="com.itheima.pojo.Role" parameterType="int">
  8. select r.*
  9. from t_role r,t_user_role ur
  10. where r.id = ur.role_id and ur.user_id = #{user_id}
  11. </select>
  12. </mapper>

根据角色id查询角色权限Mapper映射文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.zcl.dao.PermissionDao">
  6. <!--根据角色id查询权限-->
  7. <select id="findByRoleId" resultType="com.itheima.pojo.Permission" parameterType="int">
  8. select p.*
  9. from t_permission p,t_role_permission rp
  10. where p.id = rp.permission_id and rp.role_id = ${role_id}
  11. </select>
  12. </mapper>

修改dubbo的批量扫描

原因:默认配置的dubbo扫描的是Controller包下的,所以我们创建了一个新的包server用于存放权限实现类,而实现类刚好也是使用dubbo来远程调用接口查询数据库的,需要使用到dubbo就需要被扫描到

  1. <!--批量扫描-->
  2. <dubbo:annotation package="com.zcl" />

创建springSecurity.xml配置文件

与上一篇的入门案例不同的是,SpringSecurityUserService认证提供者不需要在配置文件里面创建bean交给spring容器了,因为在类的上面已经使用@Component创建,在spring容器中已经有了,通过小写字母即可引用

如果引用认证类报红就不需要管,影响不到程序,只是IDEA的检测问题

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:security="http://www.springframework.org/schema/security"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:mvc="http://www.springframework.org/schema/mvc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/security
  10. http://www.springframework.org/schema/security/spring-security.xsd
  11. http://www.springframework.org/schema/context
  12. http://www.springframework.org/schema/context/spring-context.xsd
  13. http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  14.  
  15. <!--配置哪些资源匿名可以访问的资源(不登录页可以访问)-->
  16. <security:http security="none" pattern="/login.html"></security:http>
  17. <security:http security="none" pattern="/css/**"></security:http>
  18. <security:http security="none" pattern="/js/**"></security:http>
  19. <security:http security="none" pattern="/img/**"></security:http>
  20. <security:http security="none" pattern="/plugins/**"></security:http>
  21.  
  22. <!--
  23. http:用于定义相关权限控制
  24. auto-config:是否自动配置
  25. 设置为true时框架会提供默认的一些配置,例如提供默认的登录页面、登出处理等
  26. 设置为false时需要显示提供登录表单配置,否则会报错
  27. use-expressions:用于指定intercept-url中的access属性是否使用表达式
  28. -->
  29. <security:http auto-config="true" use-expressions="true">
  30. <security:headers>
  31. <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
  32. <security:frame-options policy="SAMEORIGIN"></security:frame-options>
  33. </security:headers>
  34. <!--
  35. intercept-url:定义一个拦截规则
  36. pattern:对哪些url进行权限控制
  37. access:在请求对应的URL时需要什么权限,默认配置时它应该是一个以逗号分隔的角色列表,
  38. 请求的用户只需拥有其中的一个角色就能成功访问对应的URL
  39. -->
  40. <!--只需要认证通过就可以访问-->
  41. <security:intercept-url pattern="/pages/**" access="isAuthenticated()"/>
  42.  
  43. <!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表单-->
  44. <security:form-login
  45. login-page="/login.html"
  46. username-parameter="username"
  47. password-parameter="password"
  48. login-processing-url="/login.do"
  49. default-target-url="/pages/main.html"
  50. authentication-failure-url="/login.html"/>
  51.  
  52. <!--csrf:对应CsrfFilter过滤器
  53. disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403) -->
  54. <security:csrf disabled="true"/>
  55.  
  56. <!--
  57. logout:退出登录
  58. logout-url:退出登录操作对应的请求路径
  59. logout-success-url:退出登录后的跳转页面
  60. -->
  61. <security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true"/>
  62. </security:http>
  63. <!--authentication-manager:认证管理器,用于处理认证操作-->
  64. <security:authentication-manager>
  65. <!--authentication-provider:认证提供者,执行具体的认证逻辑-->
  66. <security:authentication-provider user-service-ref="springSecurityUserService">
  67. <!--引用密码加密处理bean-->
  68. <security:password-encoder ref="passwordEncoder"/>
  69. </security:authentication-provider>
  70. </security:authentication-manager>
  71.  
  72. <!--配置密码加密对象-->
  73. <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
  74.  
  75. <!--开启注解方式权限控制-->
  76. <security:global-method-security pre-post-annotations="enabled"/>
  77. </beans>

注意:<security:headers>的配置,如果没有配置这个对象就会访问不了嵌套的页面,哪怕是登录了也不行

在springmvc.xml配置文件中引入springSecurity.xml配置文件

  1. <import resource="spring-security.xml"/>

测试

  1. 账号为:admin
  2. 密码:admin
  3. admin加密后的形式为(存储到数据库):$2a$10$LPbhiutR34wKvjv3Qb8zBu7piw5hG3.IlQMAI3e/D1Y0DJ/mMSkYa

3、在控制器上实现注解鉴权

注意:是在每一个控制器上面添加不同的权限,设置权限的只不能乱设置需要与数据库进行比对的才可以

  1. // 添加数据
  2. @PreAuthorize("hasAuthority('CHECKITEM_ADD')")
  3.  
  4. // 查询数据
  5. @PreAuthorize("hasAuthority('CHECKITEM_QUERY')")
  6.  
  7. // 删除数据
  8. @PreAuthorize("hasAuthority('CHECKITEM_DELETE')")
  9.  
  10. // 修改数据
  11. @PreAuthorize("hasAuthority('CHECKITEM_EDIT')")

"hasAuthority('CHECKITEM_ADD')"里面的值需要与数据库的权限值一致

模拟没有权限删除数据:

1、登录第二个账户:xiaoming

2、账户中没有删除检查项,所以我们就已删除来测试

3、点击删除的时候前端页面不会提示,查看后端控制器代码,发现被拦截了,如下报错:

4、切换回有删除权限的用户,删除查看效果

3.1、完善前端页面访问权限不足提示

在前端代码中编写一个方法被多个请求不成功函数所调用

  1. showMessage(r){
  2. if(r == 'Error: Request failed with status code 403'){
  3. //权限不足
  4. this.$message.error('无访问权限');
  5. return;
  6. }else{
  7. this.$message.error('未知错误');
  8. return;
  9. }
  10. }

在所有的请求方法上添加一个catch事件调用函数

  1. // 发送删除数据
  2. axios.get("/checkitem/delete.do?id="+row.id).then((res) => {
  3. // ... 回调方法
  4. }).catch ((r) => {
  5. this.showMessage(r);
  6. });

当用户操作时如果没有权限那么后端控制器就会将请求拦截下来,并在后端控制台打印拦截提示,同时前端页面回根据返回的报错类型做出无权限的提示信息,从而提高用户体验

4、请求获取当前登录的用户名信息

请求控制器获取用户名信息返回页面模型绑定给username用于展示

  1. // 发送ajax请求获取当前登录的用户名,展示到页面中
  2. axios.get("/user/getUsername.do").then((res) => {
  3. if(res.data.flag){
  4. this.username = res.data.data;
  5. }
  6. })

请求后端控制器编写

  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController {
  4.  
  5. @RequestMapping("/getUsername")
  6. public Result getUsername(){
  7. // 当springsecurity完成认证后,会将当前用户信息保存到框架提供的上下文对象中
  8. User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  9. if (user != null) {
  10. System.out.println(user.getUsername());
  11. return new Result(true, MessageConstant.GET_USERNAME_SUCCESS,user.getUsername());
  12. }
  13. return new Result(false, MessageConstant.GET_USERNAME_FAIL);
  14. }
  15. }

5、用户退出

前端请求

  1. <el-dropdown-item divided>
  2. <span style="display:block;"><a href="/logout.do" rel="external nofollow" >退出</a></span>
  3. </el-dropdown-item>

后端配置文件中进行退出跳转设置

  1. <!--
  2. logout:退出登录
  3. logout-url:退出登录操作对应的请求路径
  4. logout-success-url:退出登录后的跳转页面
  5. -->
  6. <security:logout logout-url="/logout.do"
  7. logout-success-url="/login.html" invalidate-session="true"/>

到此这篇关于详解如何在项目中应用SpringSecurity权限控制的文章就介绍到这了,更多相关SpringSecurity权限控制内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号