目錄
1.搭建SSM框架
?1.1.引入相關(guān)的依賴(lài)
1.2.?spring配置文件
1.3. web.xml配置文件
1.4.配置Tomcat并啟動(dòng)
2.ssm整合shiro---認(rèn)證功能
?(1).引入依賴(lài)
(2).修改spring配置文件
(3).修改web.xml文件
(4).新建login.jsp(登錄頁(yè)面)
(5).新建success.jsp(登錄成功后跳轉(zhuǎn)到此)
(6).創(chuàng)建User實(shí)體類(lèi)
(7).創(chuàng)建LoginVo
(8).controller層
(9).創(chuàng)建MyRealm
(10).創(chuàng)建UserService接口
(11).創(chuàng)建UserServiceImpl實(shí)現(xiàn)類(lèi)
(12).創(chuàng)建dao方法
(13).創(chuàng)建dao方法的映射代碼UserMapper.xml
(14).啟動(dòng)Tomcat測(cè)試
3.ssm整合shiro---授權(quán)
(1).創(chuàng)建Permission實(shí)體類(lèi)
(2).修改myRealm
(3).UserService添加
(4).UserServiceImpl
(5).userDao
(6).UserMapper.xml
(7).success.jsp
(8).新建UserController
(9).測(cè)試
(10).shiro注解
(11).處理權(quán)限不足的異常
1.創(chuàng)建一個(gè)異常處理類(lèi)
2.創(chuàng)建一個(gè)403.jsp
3.測(cè)試
3.ssm整合shiro前后端分離
以下后臺(tái)返回結(jié)果改為json格式數(shù)據(jù):
3.1.根據(jù)賬號(hào)和密碼登錄后---返回json數(shù)據(jù)
(1).定義一個(gè)統(tǒng)一的json類(lèi)
(2) 修改controller代碼
3.2.權(quán)限不足時(shí)---返回json數(shù)據(jù)
(1).修改權(quán)限不足的異常處理類(lèi)
3.3.未登錄時(shí)---返回json數(shù)據(jù)
(1).第一種: 未登錄跳轉(zhuǎn)到一個(gè)接口路徑
?(2).第二種: 定義過(guò)濾器
測(cè)試
4.shiro權(quán)限對(duì)象緩存到redis中
(1).依賴(lài)
(2).修改spring配置文件
1.搭建SSM框架
?1.1.引入相關(guān)的依賴(lài)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>shiro-ssm</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>shiro-ssm Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!--mysql驅(qū)動(dòng)--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> </dependency> <!--spring的相關(guān)依賴(lài)--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.15.RELEASE</version> </dependency> <!--mybatis的依賴(lài)--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> </dependency> <!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> <!--jsp servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!--druid依賴(lài)--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> </dependencies> <build> <finalName>shiro-ssm</finalName> </build> </project>
1.2.?spring配置文件
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--包掃描--> <context:component-scan base-package="com.wqg"/> <!--2.注解驅(qū)動(dòng)--> <mvc:annotation-driven/> <!--3.靜態(tài)資源放行--> <mvc:default-servlet-handler/> <!--4.視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!--數(shù)據(jù)源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root"/> <property name="password" value="root"/> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai"/> </bean> <!--SqlSessionFactory 加載mybatis的配置--> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--映射文件所在的路徑--> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!--7.設(shè)置dao接口的代理實(shí)現(xiàn)類(lèi)--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sessionFactory"/> <!--dao接口所在的包--> <property name="basePackage" value="com.wqg.dao"/> </bean> <!--事務(wù)管理--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--開(kāi)啟事務(wù)的注解驅(qū)動(dòng)--> <tx:annotation-driven/> </beans>
1.3. web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> <!--tomcat啟動(dòng)時(shí)加載該類(lèi)--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
1.4.配置Tomcat并啟動(dòng)
2.ssm整合shiro---認(rèn)證功能
數(shù)據(jù)庫(kù)結(jié)構(gòu)
/* Navicat Premium Data Transfer Source Server : 實(shí)訓(xùn) Source Server Type : MySQL Source Server Version : 80032 Source Host : localhost:3306 Source Schema : shiro Target Server Type : MySQL Target Server Version : 80032 File Encoding : 65001 Date: 06/07/2023 11:16:35 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for permission -- ---------------------------- DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `perid` int(0) NOT NULL AUTO_INCREMENT, `pername` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `percode` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`perid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of permission -- ---------------------------- INSERT INTO `permission` VALUES (1, '查詢(xún)用戶(hù)信息', 'user:query'); INSERT INTO `permission` VALUES (2, '修改用戶(hù)', 'user:update'); INSERT INTO `permission` VALUES (3, '刪除用戶(hù)', 'user:delete'); INSERT INTO `permission` VALUES (4, '添加用戶(hù)', 'user:insert'); INSERT INTO `permission` VALUES (5, '導(dǎo)出用戶(hù)', 'user:export'); -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `roleid` int(0) NOT NULL AUTO_INCREMENT, `rolename` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`roleid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES (1, '倉(cāng)管管理員'); INSERT INTO `role` VALUES (2, 'CEO'); INSERT INTO `role` VALUES (3, '保安'); -- ---------------------------- -- Table structure for role_permission -- ---------------------------- DROP TABLE IF EXISTS `role_permission`; CREATE TABLE `role_permission` ( `perid` int(0) NOT NULL, `roleid` int(0) NOT NULL, PRIMARY KEY (`perid`, `roleid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of role_permission -- ---------------------------- INSERT INTO `role_permission` VALUES (1, 1); INSERT INTO `role_permission` VALUES (1, 2); INSERT INTO `role_permission` VALUES (1, 3); INSERT INTO `role_permission` VALUES (2, 1); INSERT INTO `role_permission` VALUES (2, 2); INSERT INTO `role_permission` VALUES (3, 1); INSERT INTO `role_permission` VALUES (3, 2); INSERT INTO `role_permission` VALUES (4, 1); INSERT INTO `role_permission` VALUES (5, 3); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `userid` int(0) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `userpwd` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `salt` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`userid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'zhangsan', '4b05a8716a430f71c6911d2e9149092f', '男', '武漢', '07f63bbf285e4719bfee1cc2bb81db33'); INSERT INTO `user` VALUES (2, 'lisi', '99cc11855b41ff3e5f7c0af3c5090a8c', '女', '北京', '2d7e37f019144764ac02aa7220929f93'); INSERT INTO `user` VALUES (3, 'wangwu', '6d70c027801af4dc892ab340d4bf73b6', '女', '成都', '99f6bf1b540145699e6e5c90480105b0'); -- ---------------------------- -- Table structure for user_role -- ---------------------------- DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `userid` int(0) NOT NULL, `roleid` int(0) NOT NULL, PRIMARY KEY (`userid`, `roleid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user_role -- ---------------------------- INSERT INTO `user_role` VALUES (1, 1); INSERT INTO `user_role` VALUES (2, 2); INSERT INTO `user_role` VALUES (3, 3); SET FOREIGN_KEY_CHECKS = 1;
?(1).引入依賴(lài)
<!--shiro-spring整合的依賴(lài)--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency>
(2).修改spring配置文件
加入:
<!--shiro和spring整合的配置--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> </bean> <bean id="myRealm" class="com.wqg.realm.MyRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"/> </bean> <!--加密器--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <property name="hashIterations" value="1024"/> </bean> <!--shiro過(guò)濾器 id:必須和web.xml里面的過(guò)濾器配置的名稱(chēng)對(duì)應(yīng)--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--未登錄時(shí)跳轉(zhuǎn)的路徑--> <property name="loginUrl" value="/login.jsp"/> <!--過(guò)濾規(guī)則--> <property name="filterChainDefinitions"> <value> /login=anon /**=authc </value> </property> </bean>
(3).修改web.xml文件
加入:
<!--shiro的過(guò)濾器:必須和ShiroFilterFactoryBean的id一致--> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
(4).新建login.jsp(登錄頁(yè)面)
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:03 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/login" method="post"> 賬號(hào):<input type="text" name="username"/><br><br> 密碼:<input type="text" name="password"/><br><br> <input type="submit" value="登錄"/> </form> </body> </html>
(5).新建success.jsp(登錄成功后跳轉(zhuǎn)到此)
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:09 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Welcome to Henan</h1> </body> </html>
(6).創(chuàng)建User實(shí)體類(lèi)
@Data public class User { private Integer userid; private String username; private String userpwd; private String sex; private String address; private String salt; }
(7).創(chuàng)建LoginVo
@Data public class LoginVo { private String Password; private String Username; }
(8).controller層
@Controller public class LoginController { @PostMapping("/login") public String login(LoginVo loginVo){//@RequestBody接受的json對(duì)象參數(shù)。 不加:表單數(shù)據(jù)以及地址欄傳遞的數(shù)據(jù) //傳遞的數(shù)據(jù)校驗(yàn) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(loginVo.getUsername(),loginVo.getPassword()); try { subject.login(token); return "success"; //經(jīng)過(guò)視圖解析器 /WEB-INF/views/success.jsp }catch (Exception e){ e.printStackTrace(); return "redirect:/login.jsp"; } } }
(9).創(chuàng)建MyRealm
package com.wqg.realm; import com.wqg.entity.User; import com.wqg.service.UserService; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; /** * @ fileName:MyRealm * @ description: * @ author:wqg * @ createTime:2023/7/6 15:46 */ public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //1.獲取登錄賬號(hào) String username = token.getPrincipal().toString(); //2.根據(jù)賬號(hào)獲取用戶(hù)信息 User user = userService.selectByUsername(username); if (user != null) { ByteSource salt = ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getUserpwd(), salt, this.getName()); return info; } return null; } }
(10).創(chuàng)建UserService接口
public interface UserService { User selectByUsername(String username); }
(11).創(chuàng)建UserServiceImpl實(shí)現(xiàn)類(lèi)
@Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; public User selectByUsername(String username) { User user = userDao.findByUsername(username); return user; } }
(12).創(chuàng)建dao方法
public interface UserDao { User findByUsername(String username); }
(13).創(chuàng)建dao方法的映射代碼UserMapper.xml
<?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"> <!--namesapce的內(nèi)容必須和對(duì)應(yīng)的接口路徑映射--> <mapper namespace="com.wqg.dao.UserDao"> <select id="findByUsername" resultType="com.wqg.entity.User"> select * from user where username=#{username} </select> </mapper>
(14).啟動(dòng)Tomcat測(cè)試
3.ssm整合shiro---授權(quán)
(1).創(chuàng)建Permission實(shí)體類(lèi)
@Data public class Permission { private Integer perid; private String pername; private String percode; }
(2).修改myRealm
//授權(quán) protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //獲取當(dāng)前登錄者的賬號(hào) User user = (User) principals.getPrimaryPrincipal(); //調(diào)用userSerice中的方法--根據(jù)id List<String> permissions = userService.selectPermissionByUserid(user.getUserid()); if (permissions.size() != 0) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permissions); return info; } return null; }
(3).UserService添加
List<String> selectPermissionByUserid(Integer userid);
(4).UserServiceImpl
@Override public List<String> selectPermissionByUserid(Integer userid) { List<Permission> permissionList= userDao.findPermissionByUserid(userid); List<String> collect = permissionList.stream().map(item -> item.getPercode()).collect(Collectors.toList()); return collect; }
(5).userDao
List<Permission> findPermissionByUserid(Integer userid);
(6).UserMapper.xml
<select id="findPermissionByUserid" resultType="com.wqg.entity.Permission"> select p.* from user_role ur join role_permission rp on ur.roleId=rp.roleid join permission p on rp.perid=p.perid where ur.userid=#{userId} </select>
(7).success.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:09 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <html> <head> <title>Title</title> </head> <body> <%--擁有不同權(quán)限的人登錄所看到的權(quán)限不同--%> <shiro:hasPermission name="user:query"><a href="/user/query">查詢(xún)用戶(hù)</a></shiro:hasPermission> <shiro:hasPermission name="user:update"><a href="/user/update">修改用戶(hù)</a></shiro:hasPermission> <shiro:hasPermission name="user:delete"><a href="/user/delete">刪除用戶(hù)</a></shiro:hasPermission> <shiro:hasPermission name="user:insert"><a href="/user/insert">添加用戶(hù)</a></shiro:hasPermission> <shiro:hasPermission name="user:export"><a href="/user/export">導(dǎo)出用戶(hù)</a></shiro:hasPermission> </body> </html>
(8).新建UserController
package com.wqg.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ fileName:UserController * @ description: * @ author:wqg * @ createTime:2023/7/6 16:42 */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/query") public String query(){ return "user:query------------------------"; } @GetMapping("/update") public String update(){ return "user:update------------------------"; } @GetMapping("/delete") public String delete(){ return "user:delete------------------------"; } @GetMapping("/insert") public String insert(){ return "user:insert------------------------"; } @GetMapping("/export") public String export(){ return "user:export------------------------"; } }
(9).測(cè)試
現(xiàn)在雖然可以在瀏覽器看到相應(yīng)的權(quán)限---可是可以同別的方式訪(fǎng)問(wèn)后臺(tái)對(duì)應(yīng)的資源。
shiro提供了注解。---判斷當(dāng)前是否具有該注解的權(quán)限---才會(huì)執(zhí)行對(duì)應(yīng)的資源方法
(10).shiro注解
package com.wqg.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ fileName:UserController * @ description: * @ author:wqg * @ createTime:2023/7/6 16:42 */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/query") @RequiresPermissions(value = {"user:query","user:delete"},logical = Logical.OR) //可以通過(guò)多個(gè)路徑訪(fǎng)問(wèn)內(nèi)部資源 //@RequiresPermissions(value = "user:query") public String query(){ return "user:query------------------------"; } @GetMapping("/update") @RequiresPermissions(value = "user:update") public String update(){ return "user:update------------------------"; } @GetMapping("/delete") @RequiresPermissions(value = "user:delete") public String delete(){ return "user:delete------------------------"; } @GetMapping("/insert") @RequiresPermissions(value = "user:insert") public String insert(){ return "user:insert------------------------"; } @GetMapping("/export") @RequiresPermissions(value = "user:export") //該注解不能被識(shí)別 public String export(){ return "user:export------------------------"; } }
發(fā)現(xiàn)上面注解不生效-----spring沒(méi)有開(kāi)啟該注解的驅(qū)動(dòng)---spring配置文件加入如下內(nèi)容
<!-- 啟動(dòng)Shrio的注解 shiro加在controller應(yīng)該屬于springmvc的配置 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean>
測(cè)試:
在查詢(xún)用戶(hù) 中輸入當(dāng)前用戶(hù)沒(méi)有的權(quán)限的地址會(huì)跳轉(zhuǎn)失敗,證明測(cè)試成功
(11).處理權(quán)限不足的異常
處理上方權(quán)限不足導(dǎo)致的500報(bào)錯(cuò)
1.創(chuàng)建一個(gè)異常處理類(lèi)
把上面拋出的異常放入ExceptionHandler注解中
@ControllerAdvice public class MyHandler { //捕獲異常 @ExceptionHandler(value = UnauthorizedException.class) public String unauthorizedException(UnauthorizedException e){ e.printStackTrace(); return "403"; } }
2.創(chuàng)建一個(gè)403.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/7 Time: 13:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 權(quán)限不足~~~~~ </body> </html>
3.測(cè)試
4.ssm整合shiro前后端分離
前后分離------后臺(tái)返回的都是json數(shù)據(jù)
以下后臺(tái)返回結(jié)果改為json格式數(shù)據(jù):
根據(jù)賬號(hào)和密碼登錄后
權(quán)限不足時(shí)
未登錄
4.1.根據(jù)賬號(hào)和密碼登錄后---返回json數(shù)據(jù)
(1).定義一個(gè)統(tǒng)一的json類(lèi)
@Data @NoArgsConstructor @AllArgsConstructor public class Result { private Integer code; private String msg; private Object data; }
(2) 修改controller代碼
@PostMapping("/login") @ResponseBody public Result login(LoginVo loginVo){//@RequestBody接受的json對(duì)象參數(shù)。 不加:表單數(shù)據(jù)以及地址欄傳遞的數(shù)據(jù) //傳遞的數(shù)據(jù)校驗(yàn) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(loginVo.getUsername(),loginVo.getPassword()); try { subject.login(token); return new Result(200,"登錄成功",null); }catch (Exception e){ e.printStackTrace(); return new Result(500,"登錄失敗",null); } }
4.2.權(quán)限不足時(shí)---返回json數(shù)據(jù)
(1).修改權(quán)限不足的異常處理類(lèi)
//@ControllerAdvice:處理controller中出現(xiàn)的異常,該類(lèi)注解必須能被spring掃描到 @ControllerAdvice public class MyHandler { //捕獲異常 @ExceptionHandler(value = UnauthorizedException.class) @ResponseBody public Result unauthorizedException(UnauthorizedException e) { e.printStackTrace(); return new Result(403, "權(quán)限不足", null); } }
4.3.未登錄時(shí)---返回json數(shù)據(jù)
(1).第一種: 未登錄跳轉(zhuǎn)到一個(gè)接口路徑
?
?(2).第二種: 定義過(guò)濾器
?加入依賴(lài)
public class LoginFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 設(shè)置響應(yīng)的內(nèi)容類(lèi)型為JSON,并使用UTF-8編碼 response.setContentType("application/json;charset=utf-8"); // 獲取用于寫(xiě)入響應(yīng)的PrintWriter對(duì)象 PrintWriter writer = response.getWriter(); // 創(chuàng)建一個(gè)Result對(duì)象,包含401狀態(tài)碼和提示信息 Result result = new Result(401, "請(qǐng)先登錄---", null); // 將Result對(duì)象轉(zhuǎn)換為JSON字符串 String jsonString = JSON.toJSONString(result); // 將JSON字符串寫(xiě)入響應(yīng) writer.println(jsonString); // 刷新并關(guān)閉PrintWriter對(duì)象 writer.flush(); writer.close(); // 返回false,表示請(qǐng)求應(yīng)在此處停止 return false; } }
修改spring配置文件
測(cè)試
5.shiro權(quán)限對(duì)象緩存到redis中
目的:避免頻繁的查詢(xún)數(shù)據(jù)庫(kù)
(1).依賴(lài)
<!--shiro和redis整合的依賴(lài)--> <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>2.4.6</version> </dependency>
(2).修改spring配置文件
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-551038.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-551038.html
到了這里,關(guān)于SSM+Shiro安全框架整合(完成安全認(rèn)證--登錄+權(quán)限授權(quán))+ssm整合shiro前后端分離的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!