詳解如何在項目中應用SpringSecurity權限控制
要進行認證和授權需要前面課程中提到的權限模型涉及的7張表支撐,因為用戶信息、權限信息、菜單信息、角色信息、關聯信息等都保存在這7張表中,也就是這些表中的數據是我們進行認證和授權的依據。所以在真正進行認證和授權之前需要對這些數據進行管理,即我們需要開發如下一些功能:
1、權限數據管理(增刪改查)
2、菜單數據管理(增刪改查)
3、角色數據管理(增刪改查、角色關聯權限、角色關聯菜單)
4、用戶數據管理(增刪改查、用戶關聯角色)
數據庫數據實現導入,簡化上面的4步步驟
DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `birthday` date DEFAULT NULL, `gender` varchar(1) DEFAULT NULL, `username` varchar(32) DEFAULT NULL, `password` varchar(256) DEFAULT NULL, `remark` varchar(32) DEFAULT NULL, `station` varchar(1) DEFAULT NULL, `telephone` varchar(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO `t_user` VALUES ('1', null, null, 'admin', '$2a$10$u/BcsUUqZNWUxdmDhbnoeeobJy6IBsL1Gn/S0dMxI2RbSgnMKJ.4a', null, null, null); INSERT INTO `t_user` VALUES ('2', null, null, 'xiaoming', '$2a$10$3xW2nBjwBM3rx1LoYprVsemNri5bvxeOd/QfmO7UDFQhW2HRHLi.C', null, null, null); INSERT INTO `t_user` VALUES ('3', null, null, 'test', '$2a$10$zYJRscVUgHX1wqwu90WereuTmIg6h/JGirGG4SWBsZ60wVPCgtF8W', null, null, null); DROP TABLE IF EXISTS `t_user_role`; CREATE TABLE `t_user_role` ( `user_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`role_id`), KEY `FK_Reference_8` (`role_id`), CONSTRAINT `FK_Reference_7` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`), CONSTRAINT `FK_Reference_8` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_user_role -- ---------------------------- INSERT INTO `t_user_role` VALUES ('1', '1'); INSERT INTO `t_user_role` VALUES ('2', '2'); DROP TABLE IF EXISTS `t_permission`; CREATE TABLE `t_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `keyword` varchar(64) DEFAULT NULL, `description` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_permission -- ---------------------------- INSERT INTO `t_permission` VALUES ('1', '新增檢查項', 'CHECKITEM_ADD', null); INSERT INTO `t_permission` VALUES ('2', '刪除檢查項', 'CHECKITEM_DELETE', null); INSERT INTO `t_permission` VALUES ('3', '編輯檢查項', 'CHECKITEM_EDIT', null); INSERT INTO `t_permission` VALUES ('4', '查詢檢查項', 'CHECKITEM_QUERY', null); INSERT INTO `t_permission` VALUES ('5', '新增檢查組', 'CHECKGROUP_ADD', null); INSERT INTO `t_permission` VALUES ('6', '刪除檢查組', 'CHECKGROUP_DELETE', null); INSERT INTO `t_permission` VALUES ('7', '編輯檢查組', 'CHECKGROUP_EDIT', null); INSERT INTO `t_permission` VALUES ('8', '查詢檢查組', 'CHECKGROUP_QUERY', null); INSERT INTO `t_permission` VALUES ('9', '新增套餐', 'SETMEAL_ADD', null); INSERT INTO `t_permission` VALUES ('10', '刪除套餐', 'SETMEAL_DELETE', null); INSERT INTO `t_permission` VALUES ('11', '編輯套餐', 'SETMEAL_EDIT', null); INSERT INTO `t_permission` VALUES ('12', '查詢套餐', 'SETMEAL_QUERY', null); INSERT INTO `t_permission` VALUES ('13', '預約設置', 'ORDERSETTING', null); INSERT INTO `t_permission` VALUES ('14', '查看統計報表', 'REPORT_VIEW', null); INSERT INTO `t_permission` VALUES ('15', '新增菜單', 'MENU_ADD', null); INSERT INTO `t_permission` VALUES ('16', '刪除菜單', 'MENU_DELETE', null); INSERT INTO `t_permission` VALUES ('17', '編輯菜單', 'MENU_EDIT', null); INSERT INTO `t_permission` VALUES ('18', '查詢菜單', 'MENU_QUERY', null); INSERT INTO `t_permission` VALUES ('19', '新增角色', 'ROLE_ADD', null); INSERT INTO `t_permission` VALUES ('20', '刪除角色', 'ROLE_DELETE', null); INSERT INTO `t_permission` VALUES ('21', '編輯角色', 'ROLE_EDIT', null); INSERT INTO `t_permission` VALUES ('22', '查詢角色', 'ROLE_QUERY', null); INSERT INTO `t_permission` VALUES ('23', '新增用戶', 'USER_ADD', null); INSERT INTO `t_permission` VALUES ('24', '刪除用戶', 'USER_DELETE', null); INSERT INTO `t_permission` VALUES ('25', '編輯用戶', 'USER_EDIT', null); INSERT INTO `t_permission` VALUES ('26', '查詢用戶', 'USER_QUERY', null); -- ---------------------------- -- Table structure for `t_role` -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `keyword` varchar(64) DEFAULT NULL, `description` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO `t_role` VALUES ('1', '系統管理員', 'ROLE_ADMIN', null); INSERT INTO `t_role` VALUES ('2', '健康管理師', 'ROLE_HEALTH_MANAGER', null); -- ---------------------------- -- Table structure for `t_role_menu` -- ---------------------------- DROP TABLE IF EXISTS `t_role_menu`; CREATE TABLE `t_role_menu` ( `role_id` int(11) NOT NULL, `menu_id` int(11) NOT NULL, PRIMARY KEY (`role_id`,`menu_id`), KEY `FK_Reference_10` (`menu_id`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`menu_id`) REFERENCES `t_menu` (`id`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_role_menu -- ---------------------------- INSERT INTO `t_role_menu` VALUES ('1', '1'); INSERT INTO `t_role_menu` VALUES ('2', '1'); INSERT INTO `t_role_menu` VALUES ('1', '2'); INSERT INTO `t_role_menu` VALUES ('2', '2'); INSERT INTO `t_role_menu` VALUES ('1', '3'); INSERT INTO `t_role_menu` VALUES ('2', '3'); INSERT INTO `t_role_menu` VALUES ('1', '4'); INSERT INTO `t_role_menu` VALUES ('2', '4'); INSERT INTO `t_role_menu` VALUES ('1', '5'); INSERT INTO `t_role_menu` VALUES ('1', '6'); INSERT INTO `t_role_menu` VALUES ('1', '7'); INSERT INTO `t_role_menu` VALUES ('1', '8'); INSERT INTO `t_role_menu` VALUES ('1', '9'); INSERT INTO `t_role_menu` VALUES ('1', '10'); INSERT INTO `t_role_menu` VALUES ('1', '11'); INSERT INTO `t_role_menu` VALUES ('1', '12'); INSERT INTO `t_role_menu` VALUES ('1', '13'); INSERT INTO `t_role_menu` VALUES ('1', '14'); INSERT INTO `t_role_menu` VALUES ('1', '15'); INSERT INTO `t_role_menu` VALUES ('1', '16'); INSERT INTO `t_role_menu` VALUES ('1', '17'); INSERT INTO `t_role_menu` VALUES ('1', '18'); INSERT INTO `t_role_menu` VALUES ('1', '19'); INSERT INTO `t_role_menu` VALUES ('1', '20'); INSERT INTO `t_role_menu` VALUES ('1', '21'); -- ---------------------------- -- Table structure for `t_role_permission` -- ---------------------------- DROP TABLE IF EXISTS `t_role_permission`; CREATE TABLE `t_role_permission` ( `role_id` int(11) NOT NULL, `permission_id` int(11) NOT NULL, PRIMARY KEY (`role_id`,`permission_id`), KEY `FK_Reference_12` (`permission_id`), CONSTRAINT `FK_Reference_11` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`), CONSTRAINT `FK_Reference_12` FOREIGN KEY (`permission_id`) REFERENCES `t_permission` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_role_permission -- ---------------------------- INSERT INTO `t_role_permission` VALUES ('1', '1'); INSERT INTO `t_role_permission` VALUES ('2', '1'); INSERT INTO `t_role_permission` VALUES ('1', '2'); INSERT INTO `t_role_permission` VALUES ('2', '2'); INSERT INTO `t_role_permission` VALUES ('1', '3'); INSERT INTO `t_role_permission` VALUES ('2', '3'); INSERT INTO `t_role_permission` VALUES ('1', '4'); INSERT INTO `t_role_permission` VALUES ('2', '4'); INSERT INTO `t_role_permission` VALUES ('1', '5'); INSERT INTO `t_role_permission` VALUES ('2', '5'); INSERT INTO `t_role_permission` VALUES ('1', '6'); INSERT INTO `t_role_permission` VALUES ('2', '6'); INSERT INTO `t_role_permission` VALUES ('1', '7'); INSERT INTO `t_role_permission` VALUES ('2', '7'); INSERT INTO `t_role_permission` VALUES ('1', '8'); INSERT INTO `t_role_permission` VALUES ('2', '8'); INSERT INTO `t_role_permission` VALUES ('1', '9'); INSERT INTO `t_role_permission` VALUES ('2', '9'); INSERT INTO `t_role_permission` VALUES ('1', '10'); INSERT INTO `t_role_permission` VALUES ('2', '10'); INSERT INTO `t_role_permission` VALUES ('1', '11'); INSERT INTO `t_role_permission` VALUES ('2', '11'); INSERT INTO `t_role_permission` VALUES ('1', '12'); INSERT INTO `t_role_permission` VALUES ('2', '12'); INSERT INTO `t_role_permission` VALUES ('1', '13'); INSERT INTO `t_role_permission` VALUES ('2', '13'); INSERT INTO `t_role_permission` VALUES ('1', '14'); INSERT INTO `t_role_permission` VALUES ('2', '14'); INSERT INTO `t_role_permission` VALUES ('1', '15'); INSERT INTO `t_role_permission` VALUES ('1', '16'); INSERT INTO `t_role_permission` VALUES ('1', '17'); INSERT INTO `t_role_permission` VALUES ('1', '18'); INSERT INTO `t_role_permission` VALUES ('1', '19'); INSERT INTO `t_role_permission` VALUES ('1', '20'); INSERT INTO `t_role_permission` VALUES ('1', '21'); INSERT INTO `t_role_permission` VALUES ('1', '22'); INSERT INTO `t_role_permission` VALUES ('1', '23'); INSERT INTO `t_role_permission` VALUES ('1', '24'); INSERT INTO `t_role_permission` VALUES ('1', '25'); INSERT INTO `t_role_permission` VALUES ('1', '26');
1、Spring Security環境準備
pom.xml中導入Spring Security的maven坐標,目前版本使用的是
5.0.5.RELEASE
,版本如果過高可能就會導致不同的報錯
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.security.version}</version> </dependency>
1.1、在health_backend工程的web.xml文件中配置用於整合Spring Security框架的過濾器DelegatingFilterProxy
<!--委派過濾器,用於整合其他框架--> <filter> <!--整合spring security時,此過濾器的名稱固定springSecurityFilterChain--> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <!--註意區分放置的位置,有嚴格的先後順序--> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2、實現認證和授權
在health_backend工程中按照Spring Security框架要求提供SpringSecurityUserService,並且實現UserDetailsService接口
package com.zcl.security; import com.alibaba.dubbo.config.annotation.Reference; import com.itheima.pojo.Permission; import com.itheima.pojo.Role; import com.itheima.pojo.User; import com.zcl.service.UserService; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * 項目名稱:health_parent * 描述:SpringSecurity實現認證和授權 * * @author zhong * @date 2022-06-24 12:09 */ @Component public class SpringSecurityUserService implements UserDetailsService { /** * 使用dubbo網絡遠程調用服務提供方查詢用戶數據 */ @Reference private UserService userService; /** * 根據用戶名查詢數據庫獲取用戶信息 * @param username * @return * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userService.findByUsername(username); if(user == null) {return null;}; List<GrantedAuthority> list = new ArrayList<>(); // 動態為當前用戶授權 Set<Role> roles = user.getRoles(); // 遍歷角色集合,為用戶授予角色 for (Role role : roles) { // 為用戶授予角色 list.add(new SimpleGrantedAuthority(role.getKeyword())); // 獲取權限 Set<Permission> permissions = role.getPermissions(); // 遍歷權限,為角色授權 for (Permission permission : permissions) { list.add(new SimpleGrantedAuthority(permission.getKeyword())); } } /* * 將密碼交由框架比對 * 參數一:賬號 * 參數二:查詢數據庫的密碼,已加密的 * 參數三:用戶角色所具有的權限 */ org.springframework.security.core.userdetails.User UserSecurity = new org.springframework.security.core.userdetails.User(username,user.getPassword(),list); return UserSecurity; } }
創建遠程調用的UserService
接口
public interface UserService { /** * 根據登錄名查詢用戶數據 * @param username * @return */ User findByUsername(String username); }
創建接口實現類
需要註入數據訪問層來完成數據的查詢,用戶、角色、權限各自創建一個dao和映射文件
package com.zcl.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.itheima.pojo.Permission; import com.itheima.pojo.Role; import com.itheima.pojo.User; import com.zcl.dao.PermissionDao; import com.zcl.dao.RoleDao; import com.zcl.dao.UserDao; import com.zcl.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.util.Set; /** * 項目名稱:health_parent * 描述:用戶服務實現類 * * @author zhong * @date 2022-06-24 14:35 */ @Service(interfaceClass = UserService.class) @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Autowired private RoleDao roleDao; @Autowired private PermissionDao permissionDao; /** * 根據用戶名稱查詢用戶角色信息和關聯的角色信息,同時需要查詢角色關聯的權限信息 * @param username * @return */ @Override public User findByUsername(String username) { // 1、查詢用戶基本信息,不包含用戶角色信息 User user = userDao.findByUsername(username); if(user == null){ return null; } // 2、根據用戶查詢的用戶id查詢角色信息 Integer userId = user.getId(); Set<Role> roles = roleDao.findByUserId(userId); // 3、根據角色來查詢權限 for (Role role : roles) { Integer roleId = role.getId(); Set<Permission> permissions = permissionDao.findByRoleId(roleId); // 讓角色關聯權限 role.setPermissions(permissions); } // 讓用還關聯角色 user.setRoles(roles); return user; } }
創建【用戶、角色、權限】數據訪問層接口
註意:這三個接口都不是在同一個類中的,而是各自獨立的接口類,不要寫在一起
public interface UserDao { User findByUsername(String username); } public interface RoleDao { Set<Role> findByUserId(Integer userId); } public interface PermissionDao { Set<Permission> findByRoleId(Integer roleId); }
查詢用戶的Mapper映射文件查詢數據
映射文件創建在
resources
文件下,註意的是需要與dao
接口的包一致
<?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.zcl.dao.UserDao"> <!--根據用戶名稱查詢用戶信息--> <select id="findByUsername" parameterType="string" resultType="com.itheima.pojo.User"> select * from t_user where username = #{username} </select> </mapper>
根據用戶id查詢角色信息Mapper映射文件查詢
<?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.zcl.dao.RoleDao"> <!--根據用戶id查詢角色信息--> <select id="findByUserId" resultType="com.itheima.pojo.Role" parameterType="int"> select r.* from t_role r,t_user_role ur where r.id = ur.role_id and ur.user_id = #{user_id} </select> </mapper>
根據角色id查詢角色權限Mapper映射文件
<?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.zcl.dao.PermissionDao"> <!--根據角色id查詢權限--> <select id="findByRoleId" resultType="com.itheima.pojo.Permission" parameterType="int"> select p.* from t_permission p,t_role_permission rp where p.id = rp.permission_id and rp.role_id = ${role_id} </select> </mapper>
修改dubbo的批量掃描
原因:默認配置的dubbo掃描的是Controller包下的,所以我們創建瞭一個新的包server用於存放權限實現類,而實現類剛好也是使用dubbo來遠程調用接口查詢數據庫的,需要使用到dubbo就需要被掃描到
<!--批量掃描--> <dubbo:annotation package="com.zcl" />
創建springSecurity.xml配置文件
與上一篇的入門案例不同的是,
SpringSecurityUserService
認證提供者不需要在配置文件裡面創建bean交給spring容器瞭,因為在類的上面已經使用@Component
創建,在spring容器中已經有瞭,通過小寫字母即可引用如果引用認證類報紅就不需要管,影響不到程序,隻是IDEA的檢測問題
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--配置哪些資源匿名可以訪問的資源(不登錄頁可以訪問)--> <security:http security="none" pattern="/login.html"></security:http> <security:http security="none" pattern="/css/**"></security:http> <security:http security="none" pattern="/js/**"></security:http> <security:http security="none" pattern="/img/**"></security:http> <security:http security="none" pattern="/plugins/**"></security:http> <!-- http:用於定義相關權限控制 auto-config:是否自動配置 設置為true時框架會提供默認的一些配置,例如提供默認的登錄頁面、登出處理等 設置為false時需要顯示提供登錄表單配置,否則會報錯 use-expressions:用於指定intercept-url中的access屬性是否使用表達式 --> <security:http auto-config="true" use-expressions="true"> <security:headers> <!--設置在頁面可以通過iframe訪問受保護的頁面,默認為不允許訪問--> <security:frame-options policy="SAMEORIGIN"></security:frame-options> </security:headers> <!-- intercept-url:定義一個攔截規則 pattern:對哪些url進行權限控制 access:在請求對應的URL時需要什麼權限,默認配置時它應該是一個以逗號分隔的角色列表, 請求的用戶隻需擁有其中的一個角色就能成功訪問對應的URL --> <!--隻需要認證通過就可以訪問--> <security:intercept-url pattern="/pages/**" access="isAuthenticated()"/> <!--如果我們要使用自己指定的頁面作為登錄頁面,必須配置登錄表單--> <security:form-login login-page="/login.html" username-parameter="username" password-parameter="password" login-processing-url="/login.do" default-target-url="/pages/main.html" authentication-failure-url="/login.html"/> <!--csrf:對應CsrfFilter過濾器 disabled:是否啟用CsrfFilter過濾器,如果使用自定義登錄頁面需要關閉此項,否則登錄操作會被禁用(403) --> <security:csrf disabled="true"/> <!-- logout:退出登錄 logout-url:退出登錄操作對應的請求路徑 logout-success-url:退出登錄後的跳轉頁面 --> <security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true"/> </security:http> <!--authentication-manager:認證管理器,用於處理認證操作--> <security:authentication-manager> <!--authentication-provider:認證提供者,執行具體的認證邏輯--> <security:authentication-provider user-service-ref="springSecurityUserService"> <!--引用密碼加密處理bean--> <security:password-encoder ref="passwordEncoder"/> </security:authentication-provider> </security:authentication-manager> <!--配置密碼加密對象--> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <!--開啟註解方式權限控制--> <security:global-method-security pre-post-annotations="enabled"/> </beans>
註意:<security:headers>的配置,如果沒有配置這個對象就會訪問不瞭嵌套的頁面,哪怕是登錄瞭也不行
在springmvc.xml配置文件中引入springSecurity.xml
配置文件
<import resource="spring-security.xml"/>
測試
賬號為:admin 密碼:admin admin加密後的形式為(存儲到數據庫):$2a$10$LPbhiutR34wKvjv3Qb8zBu7piw5hG3.IlQMAI3e/D1Y0DJ/mMSkYa
3、在控制器上實現註解鑒權
註意:是在每一個控制器上面添加不同的權限,設置權限的隻不能亂設置需要與數據庫進行比對的才可以
// 添加數據 @PreAuthorize("hasAuthority('CHECKITEM_ADD')") // 查詢數據 @PreAuthorize("hasAuthority('CHECKITEM_QUERY')") // 刪除數據 @PreAuthorize("hasAuthority('CHECKITEM_DELETE')") // 修改數據 @PreAuthorize("hasAuthority('CHECKITEM_EDIT')")
"hasAuthority('CHECKITEM_ADD')"
裡面的值需要與數據庫的權限值一致
模擬沒有權限刪除數據:
1、登錄第二個賬戶:xiaoming
2、賬戶中沒有刪除檢查項,所以我們就已刪除來測試
3、點擊刪除的時候前端頁面不會提示,查看後端控制器代碼,發現被攔截瞭,如下報錯:
4、切換回有刪除權限的用戶,刪除查看效果
3.1、完善前端頁面訪問權限不足提示
在前端代碼中編寫一個方法被多個請求不成功函數所調用
showMessage(r){ if(r == 'Error: Request failed with status code 403'){ //權限不足 this.$message.error('無訪問權限'); return; }else{ this.$message.error('未知錯誤'); return; } }
在所有的請求方法上添加一個catch
事件調用函數
// 發送刪除數據 axios.get("/checkitem/delete.do?id="+row.id).then((res) => { // ... 回調方法 }).catch ((r) => { this.showMessage(r); });
當用戶操作時如果沒有權限那麼後端控制器就會將請求攔截下來,並在後端控制臺打印攔截提示,同時前端頁面回根據返回的報錯類型做出無權限的提示信息,從而提高用戶體驗
4、請求獲取當前登錄的用戶名信息
請求控制器獲取用戶名信息返回頁面模型綁定給
username
用於展示
// 發送ajax請求獲取當前登錄的用戶名,展示到頁面中 axios.get("/user/getUsername.do").then((res) => { if(res.data.flag){ this.username = res.data.data; } })
請求後端控制器編寫
@RestController @RequestMapping("/user") public class UserController { @RequestMapping("/getUsername") public Result getUsername(){ // 當springsecurity完成認證後,會將當前用戶信息保存到框架提供的上下文對象中 User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (user != null) { System.out.println(user.getUsername()); return new Result(true, MessageConstant.GET_USERNAME_SUCCESS,user.getUsername()); } return new Result(false, MessageConstant.GET_USERNAME_FAIL); } }
5、用戶退出
前端請求
<el-dropdown-item divided> <span style="display:block;"><a href="/logout.do" rel="external nofollow" >退出</a></span> </el-dropdown-item>
後端配置文件中進行退出跳轉設置
<!-- logout:退出登錄 logout-url:退出登錄操作對應的請求路徑 logout-success-url:退出登錄後的跳轉頁面 --> <security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true"/>
到此這篇關於詳解如何在項目中應用SpringSecurity權限控制的文章就介紹到這瞭,更多相關SpringSecurity權限控制內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring Boot + Mybatis Plus實現樹狀菜單的方法
- JavaWeb倉庫管理系統詳解
- Spring Security權限想要細化到按鈕實現示例
- SpringBoot淺析安全管理之基於數據庫認證
- Spring Security使用數據庫登錄認證授權