SpringBoot整合Shiro、Mybatis、Thymeleaf

SpringBoot整合Shiro、Mybatis、Thymeleaf

SpringBoot整合Shiro

  • 新建一个SpringBoot项目导入Thymeleaf依赖

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-java8time</artifactId>
    </dependency>
    
  • 导入SpringBoot整合Shiro依赖

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.1</version>
    </dependency>
    
  • 创建首页以及Controller

    package com.cjp.controller;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @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("/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";
            }
    
        }
    
    }
    
    
  • 新建配置ShiroConfig

    package com.cjp.config;
    
    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 3
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
    
            //添加内置过滤器
            Map<String, String> filterMap = new LinkedHashMap<>();
            //登陆拦截
            filterMap.put("/user/*","authc");
            bean.setFilterChainDefinitionMap(filterMap);
            bean.setLoginUrl("/toLogin");
            return bean;
        }
    
        //DefaultWebSecurityManager  2
        @Bean(name = "manager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
            //关联UserRealm
            manager.setRealm(userRealm);
            return manager;
        }
    
        //创建Realm对象,  需要自定义  1
        @Bean
        public UserRealm userRealm(){
            UserRealm userRealm = new UserRealm();
            return userRealm;
        }
    
    }
    
    
  • 自定义Realm对象:UserRealm

    package com.cjp.config;
    
    
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    
    //自定义的Realm
    public class UserRealm extends AuthorizingRealm {
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            String username = "cjp";
            String password = "123";
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
    
            if (!usernamePasswordToken.getUsername().equals(username)){ //用户名认证
                return null;   //抛出错误
            }
    
            return new SimpleAuthenticationInfo("",password,"");
        }
    }
    
    

项目结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GRyV694o-1659748359609)(D:\Desktop\暑假学习笔记\imag\image-20220805150601569.png)]

整合Mybatis、连接数据库、整合thymeleaf

  • 导入Mybatis,连接数据库的依赖

    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>2.1.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot</artifactId>
        <version>2.1.1</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
    
  • 配置数据库连接

    spring:
      datasource:
        username: root
        password: 123456
        url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        #Spring Boot 默认是不注入这些属性值的,需要自己绑定
        #druid 数据源专有配置
        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
    
        #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
        #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
        #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    
  • 创建实例类 User、对应的UserMapper、UserMapper.xml、UserService、UserServiceImpl

    User:

    package com.cjp.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private int id;
        private String name;
        private String pwd;
        private String perms;
    }
    

    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">
    <mapper namespace="com.cjp.mapper.UserMapper">
        <select id="queryUserByName" resultType="User" parameterType="String">
            select * from user where name = #{name}
        </select>
    </mapper>
    

    UserService:

    package com.cjp.service;
    
    import com.cjp.pojo.User;
    
    public interface UserService {
        public User queryUserByName(String name);
    }
    
    

    UserServiceImpl:

    package com.cjp.service;
    
    import com.cjp.mapper.UserMapper;
    import com.cjp.pojo.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserServiceImpl implements UserService{
    
        @Autowired
        UserMapper userMapper;
        @Override
        public User queryUserByName(String name) {
            User user = userMapper.queryUserByName(name);
            return user;
        }
    }
    
    

    配置文件中绑定:

    mybatis.type-aliases-package=com.cjp.pojo
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    
  • 修改UserRealm:

    package com.cjp.config;
    
    
    import com.cjp.pojo.User;
    import com.cjp.service.UserServiceImpl;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.subject.Subject;
    import org.springframework.beans.factory.annotation.Autowired;
    
    //自定义的Realm
    public class UserRealm extends AuthorizingRealm {
    
        @Autowired
        UserServiceImpl userService;
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("======>授权");
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //拿到当前登录的用户对象
            Subject subject = SecurityUtils.getSubject();
            User currentUser = (User) subject.getPrincipal();//拿到user对象
            //设置当前用户权限
            info.addStringPermission(currentUser.getPerms());
    
            return info;
        }
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("=======>认证");
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
            User user = userService.queryUserByName(usernamePasswordToken.getUsername());
            if (user==null){ //用户名认证
                return null;   //抛出错误
            }
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();
            session.setAttribute("userSession",user);
            return new SimpleAuthenticationInfo(user,user.getPwd(),"");
        }
    }
    
    
  • 修改ShiroConfig:

    package com.cjp.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 3
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
    
            //添加内置过滤器  拦截
            Map<String, String> filterMap = new LinkedHashMap<>();
            //授权
            filterMap.put("/user/add","perms[user:add]");
            filterMap.put("/user/update","perms[user:update]");
            //登陆拦截
            filterMap.put("/user/*","authc");
            bean.setFilterChainDefinitionMap(filterMap);
            bean.setLoginUrl("/toLogin");
            //设置未授权页面
            bean.setUnauthorizedUrl("/unauth");
            return bean;
        }
    
        //DefaultWebSecurityManager  2
        @Bean(name = "manager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
            //关联UserRealm
            manager.setRealm(userRealm);
            return manager;
        }
    
        //创建Realm对象,  需要自定义  1
        @Bean
        public UserRealm userRealm(){
            UserRealm userRealm = new UserRealm();
            return userRealm;
        }
    
        //整合ShiroDialect:用来整合Shiro thymeleaf
        @Bean
        public ShiroDialect getshiroDialect(){
            return new ShiroDialect();
        }
    
    }
    
    
  • 页面权限展示设置 导入shiro命名空间

    <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
    
  • 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>首页</title>
    </head>
    <body>
    <h1>首页</h1>
    <p th:text="${msg}"></p>
    <hr>
    <div shiro:hasPermission="user:add">
        <a th:href="@{/user/add}">添加</a>
    </div>
    <div shiro:hasPermission="user:update">
        <a th:href="@{/user/update}">修改</a>
    </div>
    </br>
    <div th:if="${session.userSession}==null">
        <a th:href="@{/toLogin}">登录</a>
    </div>
    </body>
    </html>
    
  • 项目结构

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值