2024.5.28 Tuesday
接上文【WEEK14】 【DAY1】Shiro第六部分【中文版】
目录
15.8.Shiro整合Thymeleaf
15.8.1.修改pom.xml添加依赖
15.8.1.1.shiro-thymeleaf整合包导入
官网:Maven Repository: com.github.theborakompanioni » thymeleaf-extras-shiro (mvnrepository.com)
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
15.8.1.2.当前完整的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>shiro-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro-springboot</name>
<description>shiro-springboot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<!--
Subject 用户
SecurityManager 管理所有用户
Realm 连接数据
-->
<!--shiro_thymeleaf整合-->
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--druid-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!--shiro整合spring的包-->
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
15.8.2.修改ShiroConfig.java
package com.P40.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//要配置什么:点击进入ShiroFilterFactoryBean源码查看
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon: 无需认证就可以访问
authc: 必须认证了才能访问
user: 必须拥有记住我功能才能用
perms: 拥有对某个资源的权限才能访问
role: 拥有某个角色权限
*/
//登录拦截
Map<String,String> filterMap = new LinkedHashMap<>();
//授权。正常情况下,应该跳转到未授权页面,但是此时由于只添加了以下的验证,导致直接跳转到401页面
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
// filterMap.put("/user/add","authc");
// filterMap.put("/user/update","authc");
//仅在此处修改add和update页面的访问权限后,重启项目,点击add或update都将被拦截,显示404错误,希望跳转到登录页面
filterMap.put("/user/*","authc"); //也可以使用通配符实现(替代上两行的/user/add和/user/update)
bean.setFilterChainDefinitionMap(filterMap);
//如果没有权限,则需要跳转到登录页
bean.setLoginUrl("/toLogin"); //设置登录的请求
//未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//DefaultWebSecurityManager
@Bean(name = "securityManager") //给这个类起别名,便于ShiroFilterFactoryBean调用
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ //获取UserRealm,但是这里好像不需要使用注解,可以直接调用
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//默认的DefaultWebSecurityManager类的类名是defaultWebSecurityManager,只是在这里修改成securityManager
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象,需要自定义类
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//创建时顺序是相反的(从real->DefaultWebSecurityManager->ShiroFilterFactoryBean)
//整合ShiroDialect(方言):用于整合Shiro和thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
15.8.3.修改index.html
<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<!--不在登录状态时才显示“Login 登录”的入口-->
<div shiro:notAuthenticated>
<a th:href="@{/toLogin}">Login 登录</a>
</div>
<p th:text="${msg}"></p>
<hr> <!--在 HTML 页面中创建一条水平线-->
<!--仅当用户在数据库中有对应权限时才能在页面上显示该功能入口-->
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">add</a>
</div>
<div shiro:hasPermission="user:update">
<a th:href="@{/user/update}">update</a>
</div>
<!--a标签定义超链接,用于从一个页面链接到另一个页面-->
<!--在登录状态时才显示“Sign out 退出登录”的入口-->
<hr>
<div shiro:Authenticated>
<a class="nav-link" th:href="@{/logout}" onclick="alert('已退出')">Sign out 退出登录</a><!--单词別拼错了href不是herf-->
</div>
</body>
</html>
15.8.4.给root用户开放所有权限(为了试验罢了)
15.8.5.修改MyController.java
只修改了退出登录的方法
//退出登录
@RequestMapping("/logout")
public String logout(){
Subject currentUser = SecurityUtils.getSubject();
currentUser.logout();
return "/index"; //修改成:退出登录后跳转到首页
}
15.8.6.重启
15.8.6.1.没有用户登录时
15.8.6.2.点击Login 登录
只在主页上显示该登录用户有权限的功能
15.8.6.3.点击Sign out 退出登录
修改成返回主页面了(在请求授权时是直接跳转到登录页)