• Shiro学习之SpringBoot整合


    shiro总目录:
    Shiro学习之Shiro基本使用(1)
    Shiro学习之Shiro基本使用(2)
    Shiro学习之SpringBoot整合(1)
    Shiro学习之SpringBoot整合(2)

    1.0 框架整合

    1.1 创建模块

    在这里插入图片描述

    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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    
        <modelVersion>4.0.0</modelVersion>
    
    
        <artifactId>shiro_springboot</artifactId>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.1.RELEASE</version>
            <relativePath />
            <!--   <relativePath />  我这边不加这个会报错故加上
            relativePath元素中的地址–本地仓库–远程仓库
            设定一个空值将始终从仓库中获取,不从本地路径获取。--> 
            
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring-boot-web-starter</artifactId>
                <version>1.9.0</version>
            </dependency>
    
            <!--mybatis-plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.0.5</version>
            </dependency>
    
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.46</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
        </dependencies>
    
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
    
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    1.3、添加配置文件

    添加配置文件 application.yml,添加基础配置

    mybatis-plus:
      configuration:
       log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      mapper-locations: classpath:mapper/*.xml
    spring:
      datasource:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/shirodb?characterEncoding=utf8&useSSL=false
        username: root
        password: root
      jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
    shiro:
      loginUrl: /myController/login
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1.4、添加启动类

    在这里插入图片描述

    添加启动类

    package com.yanwc.shiro;
    
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.yanwc.shiro.mapper")
    public class ShiroApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ShiroApplication.class,args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.0、登录认证整合

    2.1、登录实现认证准备

    代码层级
    在这里插入图片描述

    (1)创建库表

    CREATE DATABASE IF NOT EXISTS `shirodb` CHARACTER SET utf8mb4;
    USE `shirodb`;
    CREATE TABLE `user` (
     `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
     `name` VARCHAR(30) DEFAULT NULL COMMENT '用户名',
     `pwd` VARCHAR(50) DEFAULT NULL COMMENT '密码',
     `rid` BIGINT(20) DEFAULT NULL COMMENT '角色编号',
     PRIMARY KEY (`id`)
     ) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户表';
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    INSERT INTO `shirodb`.`user` (`id`, `name`, `pwd`, `rid`) VALUES (1, '张三', '7174f64b13022acd3c56e2781e098a5f', NULL);
    
    
    • 1
    • 2

    账号:张三 密码:z3 经过加盐3次加密得出上面的(想用的这个账号起码配置的代码要和我一样的)

    在这里插入图片描述

    (2)创建实体

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
     private Integer id;
     private String name;
     private String pwd;
     private Integer rid;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (3)创建 mapper

    @Repository
    public interface UserMapper extends BaseMapper<User> {
    }
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    (4)创建 service

    1、创建接口
    public interface UserService {
     //用户登录
     User getUserInfoByName(String name);
    }
    
    • 1
    • 2
    • 3
    • 4
    2 创建实现类
    @Service
    public class UserServiceImpl implements UserService {
     @Autowired
     private UserMapper userMapper;
     @Override
     public User getUserInfoByName(String name) {
     QueryWrapper<User> wrapper = new QueryWrapper<>();
     wrapper.eq("name",name);
     User user = userMapper.selectOne(wrapper);
     return user;
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    (5)自定义realm

    @Component
    public class MyRealm extends AuthorizingRealm {
     @Autowired
     private UserService userService;
     //自定义授权方法
     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
    principalCollection) {
     return null;
     }
     //自定义登录认证方法
     @Override
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken
    token) throws AuthenticationException {
     //1 获取用户身份信息
     String name = token.getPrincipal().toString();
     //2 调用业务层获取用户信息(数据库中)
     User user = userService.getUserInfoByName(name);
     //3 判断并将数据完成封装
     if(user!=null){
     AuthenticationInfo info = new SimpleAuthenticationInfo(
     token.getPrincipal(),
    user.getPwd(),
    ByteSource.Util.bytes("salt"),
     token.getPrincipal().toString()
     );
     return info;
     }
     return null;
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    (6)编写配置类

    @Configuration
    public class ShiroConfig {
     @Autowired
     private MyRealm myRealm;
     //配置 SecurityManager
     @Bean
     public DefaultWebSecurityManager defaultWebSecurityManager(){
     //1 创建 defaultWebSecurityManager 对象
     DefaultWebSecurityManager defaultWebSecurityManager = new
    DefaultWebSecurityManager();
     //2 创建加密对象,并设置相关属性
     HashedCredentialsMatcher matcher = new
    HashedCredentialsMatcher();
     //2.1 采用 md5 加密
     matcher.setHashAlgorithmName("md5");
     //2.2 迭代加密次数
     matcher.setHashIterations(3);
     //3 将加密对象存储到 myRealm 中
     myRealm.setCredentialsMatcher(matcher);
     //4 将 myRealm 存入 defaultWebSecurityManager 对象
     defaultWebSecurityManager.setRealm(myRealm);
     //5 返回
     return defaultWebSecurityManager;
     }
     //配置 Shiro 内置过滤器拦截范围
     @Bean
     public DefaultShiroFilterChainDefinition
    shiroFilterChainDefinition(){
     DefaultShiroFilterChainDefinition definition = new
    DefaultShiroFilterChainDefinition();
     //设置不认证可以访问的资源
    
    definition.addPathDefinition("/myController/userLogin","anon");
     definition.addPathDefinition("/login","anon");
     //设置需要进行登录认证的拦截范围
     definition.addPathDefinition("/**","authc");
     return definition;
     }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    (7)实现controller

    @Controller
    @RequestMapping("myController")
    public class MyController {
     @GetMapping("userLogin")
     @ResponseBody
     public String userLogin(String name,String pwd){
     //1 获取 Subject 对象
     Subject subject = SecurityUtils.getSubject();
     //2 封装请求数据到 token 对象中
     AuthenticationToken token = new
    UsernamePasswordToken(name,pwd);
     //3 调用 login 方法进行登录认证
     try {
     subject.login(token);
     return "登录成功";
     } catch (AuthenticationException e) {
     e.printStackTrace();
     System.out.println("登录失败");
     return "登录失败";
     }
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    (8)测试

    访问地址:http://localhost:8080/myController/userLogin?name=张三&pwd=z3
    在这里插入图片描述
    在这里插入图片描述

    即可成功;有问题可留言;大家在这里有些搞不清楚原因的请看后面章节;

  • 相关阅读:
    《计算机网络基础》期中考试试卷
    c语言进制的转换8进制转换2进制与2转8
    Redis~01 缓存:如何利用读缓存提高系统性能?
    Android基础第二天 | 字节跳动第四届青训营笔记
    记录一次mysql启动失败的原因
    互联网摸鱼日报(2023-10-12)
    C++11 - 右值引用
    Springcloud的学习笔记(二)
    计算机操作系统——概述(课程笔记)
    基于bp神经网络的pid算法,基于单神经元的pid控制
  • 原文地址:https://blog.csdn.net/qq_42055933/article/details/127562630