thymeleaf-extras-shiro 的版本比较坑,按我这个配可以省很多时间!!!
<?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.1.1.RELEASE</version>-->
<version>1.5.3.RELEASE</version>
<!--<version>3.0.0</version>-->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mybatis</groupId>
<artifactId>mybatis-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.0</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<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>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- mybatis-plus代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!-- ************mybatis-plus整合shiro************** -->
<!-- shiro-thymeleaf整合-->
<!--<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>-->
<!-- springboot-thymeleaf整合,没有这个包就进不了首页-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<!-- shiro-thymeleaf整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>3.0.1.RELEASE</version>
</dependency>
<!-- ************mybatis-plus整合shiro************** -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/ye?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
thymeleaf:
cache: false
prefix: classpath:/templates/
suffix: .html
encoding: UTF-8
content-type: text/html
mode: HTML5
mybatis-plus:
# xml文件路径
mapper-locations: classpath:mapper/*.xml
# 实体类路径
type-aliases-package: com.mybatis.pojo
configuration:
# 驼峰转换
map-underscore-to-camel-case: true
# 是否开启缓存
cache-enabled: false
# 打印sql
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 全局配置
global-config:
# 数据库字段驼峰下划线转换
db-column-underline: true
# id自增类型(数据库id自增)
@Configuration
public class ShiroConfig {
// shiroFilterFactoryBean3
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
// 设置安全管理器
bean.setSecurityManager(securityManager);
// 添加shiro的内置过滤器
// filterMap.put("/user/add","anon");
// filterMap.put("/user/update","authc");
/**
* anon : 无需认证就能访问
* authc: 必须认证了才能访问
* user: 必须拥有 记住我 功能才能用
* perms: 拥有对某个资源的权限才能用
* role: 拥有对某个角色权限才访问
*/
// 拦截
Map<String, String> filterMap = new LinkedHashMap<>();
// 授权,正常情况下,没有授权会跳转到未授权页面
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
filterMap.put("/user/delete","perms[user:delete]");
filterMap.put("/user/authTest","perms[user:authTest]");
filterMap.put("/user/anon","anon");
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
// 设置登录页面的请求
bean.setLoginUrl("/toLogin");
bean.setUnauthorizedUrl("/noAuth");
return bean;
}
// defaultWebSecurityManager2
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 关联userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
// 创建 Realm 对象,需要自定义类1
@Bean(name="userRealm")
public UserRealm userRealm(){
return new UserRealm();
}
// 整合shiroDialect: 用来整合 shiro thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo...");
// SimpleAuthorizationInfo
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//info.addStringPermission("user:add");
// 拿到当前用户对象
Subject subject = SecurityUtils.getSubject();
BasisUsr currentUser = (BasisUsr) subject.getPrincipal();// 拿到user对象
// 设置当前用户的权限
info.addStringPermission(currentUser.getEmail());
return info;
}
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthenticationInfo...");
// 用户名,密码~ 数据中取
// String name = "root";
// String password = "123456";
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
// 连接真实的数据库
BasisUsr user = userService.getUserByName(userToken.getUsername());
if(null==user){// 没有这个人
return null;
}
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
session.setAttribute("loginUser",user);
// 可以加密 MD5盐值加密
// 密码认证,shiro做~
return new SimpleAuthenticationInfo(user,user.getPwd(),"");
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserServiceImpl userService;
@PostMapping("getUser")
public List<BasisUsr> getUser(){
return userService.getByName();
}
}
@Controller
public class MyController {
@RequestMapping({"/","/index"})
public String toIndex(Model model){
model.addAttribute("msg","hello shiro");
return "index";
}
@RequestMapping("/user/add")
public String add(){
return "user/add";
}
@RequestMapping("/user/update")
public String update(){
return "user/update";
}
@RequestMapping("/user/delete")
public String delete(){
return "user/delete";
}
@RequestMapping("/user/authTest")
public String authTest(){
return "user/authTest";
}
@RequestMapping("/user/anon")
public String anon(){
return "user/anon";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}
@RequestMapping("login")
public String login(String username,String password,Model model){
// 获取当前用户
Subject subject = SecurityUtils.getSubject();
// 封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);// 执行登录方法,如果没有异常就说明ok了
return "index";
} catch (UnknownAccountException e) {// 用户名不存在
model.addAttribute("msg","用户名不存在");
return "login";
} catch (IncorrectCredentialsException e) {
model.addAttribute("msg","密码错误");
return "login";
} catch (AuthenticationException e) {
e.printStackTrace();
return "login";
}
}
@RequestMapping("/noAuth")
@ResponseBody
public String unauthorized(){
return "未经授权无法访问此页面";
}
}
public interface UserMapper extends BaseMapper<BasisUsr> {
//List getByName(String name);
List<BasisUsr> getByName();
BasisUsr getUserByName(String name);
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="getByName" resultType="com.mybatis.pojo.BasisUsr">
select * from basis_usr
select>
<select id="getUserByName" parameterType="string" resultType="com.mybatis.pojo.BasisUsr">
select * from basis_usr where nam = #{name}
select>
mapper>
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
@TableName("basis_usr")
public class BasisUsr {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField(value = "nam")
private String nam;
@TableField(value = "pwd")
private String pwd;
@TableField(value = "email")
private String email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNam() {
return nam;
}
public void setNam(String nam) {
this.nam = nam;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public interface UserService extends IService<BasisUsr> {
BasisUsr getUserByName(String name);
List<BasisUsr> getByName();
}
@Component
public class UserServiceImpl extends ServiceImpl<UserMapper, BasisUsr> implements UserService{
//@Autowired
@Resource
private UserMapper userMapper;
@Override
public BasisUsr getUserByName(String name) {
return userMapper.getUserByName(name);
}
@Override
//public BasisUsr getByName(String name) {
public List<BasisUsr> getByName() {
return userMapper.getByName();
}
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro" >
<head>
<meta charset="UTF-8"/>
<title>Titletitle>
head>
<body>
<h1>首页h1>
<div th:if="${session.loginUser==null}">
<a th:href="@{/toLogin}">登录a>
div>
<p th:text="${msg}">p>
<hr/>
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">adda>
div>
<div shiro:hasPermission="user:update">
<a th:href="@{/user/update}">updatea>
div>
<div shiro:hasPermission="user:delete">
<a th:href="@{/user/delete}">deletea>
div>
<div >
<a th:href="@{/user/authTest}">authTesta>
div>
<div >
<a th:href="@{/user/anon}">anona>
div>
body>
html>
DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>登录h1>
<hr/>
<p th:text="${msg}" style="color:red;">p>
<form th:action="@{/login}">
<p>用户名: <input type="text" name="username"/>p>
<p>密码: <input type="text" name="password"/>p>
<p><input type="submit"/>p>
form>
body>
html>
注意:以上2个页面直接放在templates包下面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>addh1>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>所有人都能看到我h1>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>authTesth1>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>deleteh1>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Titletitle>
head>
<body>
<h1>updateh1>
body>
html>
INSERT INTO `ye`.`basis_usr`(`id`, `acnt`, `pwd`, `nam`, `gdr`, `phone`, `email`, `empdat`, `lstvt`, `sflvl`, `dev`, `frzn`, `corp`, `ldr`, `lstvf`) VALUES (32, 'root', '123456', 'root', 1, NULL, 'user:add', NULL, NULL, 123, 0, 0, 6, NULL, NULL);
INSERT INTO `ye`.`basis_usr`(`id`, `acnt`, `pwd`, `nam`, `gdr`, `phone`, `email`, `empdat`, `lstvt`, `sflvl`, `dev`, `frzn`, `corp`, `ldr`, `lstvf`) VALUES (33, 'yecq', '123456', 'yecq', 1, NULL, 'user:update', NULL, NULL, 123, 0, 0, 6, NULL, NULL);
INSERT INTO `ye`.`basis_usr`(`id`, `acnt`, `pwd`, `nam`, `gdr`, `phone`, `email`, `empdat`, `lstvt`, `sflvl`, `dev`, `frzn`, `corp`, `ldr`, `lstvf`) VALUES (34, 'zhangsan', '123456', 'zhangsan', 1, NULL, 'user:delete', NULL, NULL, 123, 0, 0, 6, NULL, NULL);
INSERT INTO `ye`.`basis_usr`(`id`, `acnt`, `pwd`, `nam`, `gdr`, `phone`, `email`, `empdat`, `lstvt`, `sflvl`, `dev`, `frzn`, `corp`, `ldr`, `lstvf`) VALUES (35, 'lisi', '123456', 'lisi', 1, NULL, 'user:authTest', NULL, NULL, 123, 0, 0, 6, NULL, NULL);
mybatis-plus和lombok插件安装,不在此赘述。
springboot+shiro+mybatis-plus 权限框架集成 完结!撒花!