【WEEK13】 【DAY4】Shiro Part 4【English Version】

2024.5.23 Thursday

Continued from 【WEEK13】 【DAY3】Shiro Part 3【English Version】

Table of Contents

  • [15.6. Integrate Shiro with MyBatis](#15.6. Integrate Shiro with MyBatis)
    • [15.6.1. Modify pom.xml](#15.6.1. Modify pom.xml)
    • [15.6.2. Create application.yaml](#15.6.2. Create application.yaml)
    • [15.6.3. Connect to the database](#15.6.3. Connect to the database)
    • [15.6.4. Modify application.properties](#15.6.4. Modify application.properties)
    • [15.6.5. Create pojo folder and mapper folders (two places)](#15.6.5. Create pojo folder and mapper folders (two places))
      • [15.6.5.1. Create User.java](#15.6.5.1. Create User.java)
      • [15.6.5.2. Create UserMapper.java](#15.6.5.2. Create UserMapper.java)
      • [15.6.5.3. Create UserMapper.xml](#15.6.5.3. Create UserMapper.xml)
    • [15.6.6. Create service folder](#15.6.6. Create service folder)
      • [15.6.6.1. Create UserService.java](#15.6.6.1. Create UserService.java)
      • [15.6.6.2. Create UserServiceImpl.java](#15.6.6.2. Create UserServiceImpl.java)
      • [15.6.6.3. Unit Test](#15.6.6.3. Unit Test)
    • [15.6.7. Connect to a real database](#15.6.7. Connect to a real database)
      • [15.6.7.1. Modify UserRealm.java](#15.6.7.1. Modify UserRealm.java)
      • [15.6.7.2. Modify the User table](#15.6.7.2. Modify the User table)
      • [15.6.7.3. Restart ShiroSpringbootApplication.java](#15.6.7.3. Restart ShiroSpringbootApplication.java)
      • [15.6.7.4. Currently using general encryption](#15.6.7.4. Currently using general encryption)

15.6. Integrate Shiro with MyBatis

15.6.1. Modify pom.xml

Import 5 dependencies

xml 复制代码
<!--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>

15.6.2. Create application.yaml

Use the YAML file configuration previously used, copy and paste it, and make some modifications at the end. At this point, all contents of application.properties can be commented out without affecting use.

yaml 复制代码
spring:
  datasource:
    username: root
    password: 123456
    # If there is a time zone error, add a time zone configuration and connect it with other configurations using &
    # For example: serverTimezone=UTC
    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 does not inject these attribute values by default, so you need to bind them yourself
    # Druid-specific configuration
    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

    # Configure monitoring statistical interception filters: stat: statistical monitoring; log4j: log recording; wall: defense against SQL injection
    # If an error like java.lang.ClassNotFoundException: org.apache.log4j.Priority occurs
    # Import the log4j dependency, Maven address: https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

mybatis:
  # type-aliases-package: P40.pojo
  mapper-locations: classpath:mapper/*.xml
# Pay attention to the indentation of the three lines above, which directly determines whether there is an error

15.6.3. Connect to the database

A new mybatis database has been created

sql 复制代码
CREATE DATABASE `mybatis`;
USE `mybatis`;

CREATE TABLE `user`(
    `id` INT(20) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    `pwd` VARCHAR(30) DEFAULT NULL,
    PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `user`(`id`,`name`,`pwd`) VALUES
(1,'zhangsan','123456'),
(2,'lisi','2345678'),
(3,'wangwu','3456789');

15.6.4. Modify application.properties

xml 复制代码
spring.application.name=shiro-springboot
#mybatis.type-aliases-package=P40.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

Note here!!! The aliases starting from the second line cannot be used here (it will cause an error), so it should be commented out to run successfully!

15.6.5. Create pojo folder and mapper folders (two places)

15.6.5.1. Create User.java

java 复制代码
package com.P40.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;
}

15.6.5.2. Create UserMapper.java

java 复制代码
package com.P40.mapper;

import com.P40.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Repository
@Mapper// Whether this mapper is commented or not doesn't matter
public interface UserMapper {
    public User queryUserByName(String name);
}

15.6.5.3. Create UserMapper.xml

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.P40.mapper.UserMapper">
    <select id="queryUserByName" parameterType="String" resultType="com.P40.pojo.User">
        SELECT * FROM mybatis.user WHERE name = #{name}
    </select>
</mapper>

15.6.6. Create service folder

15.6.6.1. Create UserService.java

java 复制代码
package com.P40.service;

import com.P40.pojo.User;

public interface UserService {
    public User queryUserByName(String name);
}

15.6.6.2. Create UserServiceImpl.java

java 复制代码
package com.P40.service;

import com.P40.mapper.UserMapper;
import com.P40.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) {
        return userMapper.queryUserByName(name);
    }
}

15.6.6.3. Unit Test

Modify ShiroSpringbootApplicationTests.java

java 复制代码
package com.P40;

import com.P40.service.UserServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ShiroSpringbootApplicationTests {

    @Autowired
    UserServiceImpl userService;
    @Test
    void contextLoads() {
        System.out.println(userService.queryUserByName("lisi"));
    }

}

However, the test here cannot run 【Solved】Modified the yaml configuration file and UserMapper.xml file (the key is to remove the file aliases)

15.6.7. Connect to a real database

15.6.7.1. Modify UserRealm.java

java 复制代码
package com.P40.config;

import com.P40.pojo.User;
import com.P40.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

// UserRealm is a bean
// Custom UserRealm, must inherit AuthorizingRealm method, and then implement methods (alt+insert)
public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    // Authorization
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("do doGetAuthorizationInfo Authorization");
        return null;
    }

    // Authentication
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("do doGetAuthorizationInfo Authentication");

        // Username, password -- Data reading. The following two lines are the user data obtained by simulating connecting to the database in the early stage of programming
//        String name = "root";
//        String password = "1";

        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

//        if (!userToken.getUsername().equals(name)){
//            return null;    //Throw UnknownAccountException exception (automatically)
//        }

        // Change to connect to a real database
        User user = userService.queryUserByName(userToken.getUsername());
        if(user == null){   // This user does not exist
            return null;    // UnknownAccountException
        }

        // Password authentication, Shiro operation
//        return new SimpleAuthenticationInfo("",password,"");
        return new SimpleAuthenticationInfo("",user.getPwd(),"");
    }
}

15.6.7.2. Modify the User table

Add a new row of data

15.6.7.3. Restart ShiroSpringbootApplication.java

http://localhost:8080/toLogin

Login test according to the username and password in the User table

Login successful

Directly change the username in the URL to root, since the password is also 123456, the login status can be maintained:

If changing the username to lisi, because the password for lisi is 2345678, it shows password error and cannot log in:

Trying to log in with wangwu's account, but entering the wrong username, it shows username error and cannot log in either:

15.6.7.4. Currently using general encryption

CredentialsMatcher.java

Set breakpoints in MyController.java to check the execution process

Or set breakpoints in UserRealm.java

At this point, the password entered by the user on the web page is not encrypted in CredentialsMatcher, so the password appears explicitly in the URL (plaintext password).

Click the green "I" in the left sidebar to expand ten encryption methods, among which the default is SimpleCredentialsMatcher.

In practical use, MD5 encryption results in the same ciphertext for the same plaintext password, a more secure method is MD5 salt encryption (the username is also appended to the end of the password encrypted with MD5).

相关推荐
Coder码匠16 分钟前
Dockerfile 优化实践:从 400MB 到 80MB
java·spring boot
李慕婉学姐8 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆9 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin10 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model200510 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
武藤一雄10 小时前
C# 关于多线程如何实现需要注意的问题(持续更新)
windows·后端·microsoft·c#·.net·.netcore·死锁
荒诞硬汉10 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国10 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_9418824810 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈11 小时前
两天开发完成智能体平台
java·spring·go