搭建 springboot+shiro+mybatis-plus 权限框架(超详细)

springboot整合shiro和mybatis-plus

thymeleaf-extras-shiro 的版本比较坑,按我这个配可以省很多时间!!!

pom.xml直接上依赖版本

<?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>

application.yml

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自增)

ShiroConfig

@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();
    }

}

UserRealm

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(),"");
    }
}

UserController

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    @PostMapping("getUser")
    public List<BasisUsr> getUser(){
        return userService.getByName();
    }
}

MyController

@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 "未经授权无法访问此页面";
    }
}

mapper类

public interface UserMapper extends BaseMapper<BasisUsr> {

    //List getByName(String name);
    List<BasisUsr> getByName();

    BasisUsr getUserByName(String name);
}

mapper.xml


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>

pojo类

@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;
    }
}

UserService

public interface UserService extends IService<BasisUsr> {

    BasisUsr getUserByName(String name);

    List<BasisUsr> getByName();
}

UserServiceImpl

@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();
    }

}

前端页面

index.html

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>

login.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包下面

add.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Titletitle>
head>
<body>
<h1>addh1>
body>
html>

anon.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Titletitle>
head>
<body>
<h1>所有人都能看到我h1>
body>
html>

authTest.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Titletitle>
head>
<body>
<h1>authTesth1>
body>
html>

delete.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Titletitle>
head>
<body>
<h1>deleteh1>
body>
html>

update.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Titletitle>
head>
<body>
<h1>updateh1>
body>
html>

注意:页面位置如图所示

搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第1张图片

数据库测试数据

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);

测试数据如图

搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第2张图片

效果

root用户

搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第3张图片
搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第4张图片
搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第5张图片
搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第6张图片

lisi用户可以看到authTest页面

搭建 springboot+shiro+mybatis-plus 权限框架(超详细)_第7张图片
mybatis-plus和lombok插件安装,不在此赘述。

springboot+shiro+mybatis-plus 权限框架集成 完结!撒花!

你可能感兴趣的:(mybatis,spring,boot,java,学习,后端)