Security framework shiro

1, What is shiro

  • Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, password, and session management. With Shiro's easy to understand API, you can get any application quickly and easily, from the smallest mobile application to the largest network and enterprise application.

  • Developer: Apache nature: Java security framework
    **

2, Three core components

  • Subject: the current operating user. However, in Shiro, the concept of subject refers not only to people, but also to third-party processes, daemon accounts or other similar things. It simply means "what is currently interacting with software". Subject represents the security operations of the current user, while SecurityManager manages the security operations of all users.
  • SecurityManager: it is the core of Shiro framework. It is a typical Facade mode. Shiro manages internal component instances through SecurityManager and provides various services of security management through it.
  • Realms: realms act as a "bridge" or "connector" between Shiro and application security data. That is, when performing authentication (login) and authorization (access control) authentication on the user, Shiro will find the user and his permission information from the Realm configured by the application. In this sense, Realm is essentially a security related DAO: it encapsulates the connection details of data sources and provides relevant data to Shiro when needed. When configuring Shiro, you must specify at least one Realm for authentication and / or authorization. It is possible to configure multiple realms, but at least one is required.
  • Shiro has built-in realms that can connect a large number of secure data sources (also known as directories), such as LDAP, relational database (JDBC), text configuration resources similar to INI, attribute files, etc. If the default Realm of the system cannot meet the requirements, you can also insert your own Realm implementation representing the custom data source.

    Relationship between three core components

introduction

  • pom file dependency
 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.7.1</version>
        </dependency>

        <!-- configure logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
  • First look at the Quickstart class of the source code
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Simple Quickstart application showing how to use Shiro's API.
 * A simple quick start application that shows how to use Shiro's API.
 *
 * @author W
 * @since 0.9 RC2
 */
public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger (Quickstart.class);


    public static void main(String[] args) {

        Factory<SecurityManager> factory = new IniSecurityManagerFactory ("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance ();

        /**
         *A quick start to this simple example allows the SecurityManager to be accessed as a JVM singleton.
         Most applications don't do this,
         Instead, it depends on its container configuration or web apps xml.  This is beyond the scope of this simple quick start, so we will only do the minimum work so that you can continue to feel it.
         */
        SecurityUtils.setSecurityManager (securityManager);

        // 1 get the current user object Subject
        Subject currentUser = SecurityUtils.getSubject ();
        // 2 get the Session through the current user
        Session session = currentUser.getSession ();

        session.setAttribute ("someKey", "aValue");
        String value = (String) session.getAttribute ("someKey");
        if (value.equals ("aValue")) {
            log.info ("Subject Got it session=> " + value + "!");
        }

        //3 judge whether the current user is authenticated (let's log in to the current user so that we can check the roles and permissions)
        if (!currentUser.isAuthenticated ()) {
            //Token token
            UsernamePasswordToken token = new UsernamePasswordToken ("lonestarr", "vespa");
            token.setRememberMe (true);
            try {
                //Login operation performed
                currentUser.login (token);

            } catch (UnknownAccountException uae) {
                //Unknown account exception UnknownAccountException
                log.info ("There is no user with username of " + token.getPrincipal ());
            } catch (IncorrectCredentialsException ice) {
                //Incorrect credentials exception incorrect password
                log.info ("Password for account " + token.getPrincipal () + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info ("The account for username " + token.getPrincipal () + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error? Authentication exception
            }
        }

        //say who they are:
        //print their identifying principal (in this case, a username):
        log.info ("User [" + currentUser.getPrincipal () + "] logged in successfully.");

        //test a role:
        if (currentUser.hasRole ("schwartz")) {
            log.info ("May the Schwartz be with you!");
        } else {
            log.info ("Hello, mere mortal.");
        }
//Coarse grain size
        //test a typed permission (not instance-level)
        if (currentUser.isPermitted ("lightsaber:wield")) {
            log.info ("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info ("Sorry, lightsaber rings are for schwartz masters only.");
        }
//Fine grained
        //a (very powerful) Instance Level permission:
        if (currentUser.isPermitted ("winnebago:drive:eagle5")) {
            log.info ("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info ("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }
//cancellation
        //all done - log out!
        currentUser.logout ();

        System.exit (0);
    }
}

  • Configuration class of lo4j
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
# General Apache libraries
log4j.logger.org.apache=WARN
# Spring
log4j.logger.org.springframework=WARN
# Default Shiro logging
log4j.logger.org.apache.shiro=INFO
# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

shrio.ini original configuration

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# =============================================================================
# Quickstart INI Realm configuration
#
# For those that might not understand the references in this file, the
# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
# =============================================================================

# -----------------------------------------------------------------------------
# Users and their assigned roles
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
# -----------------------------------------------------------------------------
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# 
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5

Basic use of shiro

soringboot integration shiro
Technical support: shiro, soringboot, thymeleaf, mysql, druid, mybatis, log4j and their integrated packages

  • pom file
<dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <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>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.4.0</version>
        </dependency>
<!--        integration thymeleaf-extras-shiro-->
        <!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!--
        Subject user
        SecurityManager Manage all users
        Realm Connection data
        -->
        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- druid data source-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

Construction project

Step 1: static page templates

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Sign in</title>
</head>
<body>
<p style="color:red;" th:text="${msg}"></p>
<form th:action="@{/login}" method="post">
    user name:<input type="text" name="username"><br>
    dense&nbsp;Code:<input type="password" name="password"><br>
    <input type="submit" value="Sign in">
</form>
</body>
</html>

  • 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>home page</title>
    <style>
        a {
            color: #443399
        }
    </style>
</head>
<body>
<H1>Congratulations!</H1>
<div th:if="${session.loginUser==null}">
    <a th:href="@{/toLogin}">Sign in</a>
</div>
<div shiro:hasPermission="user:add">
    <p style="color:red;" th:text="${msg}"></p>
    <a th:href="@{/up}">up</a>&nbsp;<a th:href="@{/add}">add</a>
</div>
</body>
</html>

  • user folder
  • add.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
>
<head>
    <meta charset="UTF-8">
    <title>Add page</title>
</head>
<body>

<h1>Add page</h1>
<p style="color:red;" th:text="${msg}"></p>
</body>
</html>

  • update.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>update</title>
</head>
<body>
<h1>Modify page</h1>
<p style="color:red;" th:text="${msg}"></p>
</body>
</html>

pojo entity class

Step 2: pojo entity class

package com.kuang.w.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @ClassName : User  //Class name
 * @Description : User's encapsulation / / description
 * @Author : W //author
 * @Date: 2021/5/16  11:10
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 123L;
    private int id;
    private String name;
    private String password;
    private int tid;
    private String perms;

}


Step 3: build mapper layer (dao layer)

package com.kuang.w.mapper;

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

/**
 * @ClassName : UserMapper  //Class name
 * @Description : dao layer / / description of user name
 * @Author : W //author
 * @Date: 2021/5/16  11:13
 * @Repository Indicates that this is a dao layer
 * @Mapper Indicates that this class is mybatis injected into the container of spring
 */
@Repository
@Mapper
public interface UserMapper {
    /**
     * class queryUserByName(String name)
     *
     * @param name
     * @return user
     * @Data
     */
    User queryUserByName(String name);
}


Step 4 mapper layer (dao) interface

Step 6: implement the mapper interface 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.kuang.w.mapper.UserMapper">
    <!--Enable cache-->   <!-- The second level cache is used here. The entity class must implement the serialization interface implements Serializable  -->
    <cache/>

    <select id="queryUserByName" parameterType="String" resultType="User">
        select *
        from mybatis.user
        where name = #{name}
    </select>
</mapper>

Step 7 service layer

  • UserService interface
package com.kuang.w.service;

import com.kuang.w.pojo.User;

/**
 * @ClassName : UserService  //Class name
 * @Description : User's service layer / / description
 * @Author : W //author
 * @Date: 2021/5/16  11:32
 */
public interface UserService {
    /**
     * class queryUserByName(String name)
     *
     * @param name
     * @return user
     * @Data
     */
    User queryUserByName(String name);
}


  • UserServiceImpl class that implements the interface of UserService
package com.kuang.w.service;

import com.kuang.w.mapper.UserMapper;
import com.kuang.w.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ClassName : UserServiceImpl  //Class name
 * @Description : Implementation layer / / description of the user's service
 * @Author : W //author
 * @Date: 2021/5/16  11:34
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public User queryUserByName(String name) {
        return userMapper.queryUserByName (name);
    }
}


Step 8 controller layer (mvc control layer)

  • Controller class
package com.kuang.w.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.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * @ClassName : MyController  //Class name
 * @Description : Page Jump / / description
 * @Author : W //author
 * @Date: 2021/5/15  10:12
 */
@Controller
public class MyController {
    @RequestMapping({"/", "/index", "/a"})
    public String toIndex(Model model) {
        model.addAttribute ("msg", "hello shiro");
        return "index";
    }

    @RequestMapping({"/add", "/ad"})
    public String toadd(Model model) {
        model.addAttribute ("msg", "add");
        return "user/add";
    }

    @RequestMapping("/up")
    public String toUp(Model model) {
        model.addAttribute ("msg", "update");
        return "user/update";
    }

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "login";
    }

    @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        //1 get current user
        /**
         *   Subject user
         *         SecurityManager Manage all users
         *         Realm Connection data*/
        Subject subject = SecurityUtils.getSubject ();
        //Encapsulate user information
        UsernamePasswordToken token = new UsernamePasswordToken (username, password);
        try {
            //Method of executing login
            subject.login (token);

            return "index";
        } catch (UnknownAccountException e) {
            model.addAttribute ("msg", "User name error(UnknownAccountException)!");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute ("msg", "Password error(IncorrectCredentialsException)!");
            return "login";
        }
    }

    @RequestMapping("/noauth")
    @ResponseBody
    public String toNoauth() {
        return "You do not have permission to view!";
    }
}

Step 9 configure class config

  • ShiroConfig
package com.kuang.w.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;

/**
 * @ClassName : ShiroConfig  //Class name
 * @Description : config Configuration / / description
 * @Author : W //author
 * @Date: 2021/5/15  10:46
 */
@Configuration
public class ShiroConfig {
    /**
     * ShiroFilterFactoryBean Step 3
     * DafaultWebSecurityManager Step 2
     * To create a realm object, you need to customize the class: Step 1
     */
    /**
     * ShiroFilterFactoryBean Step 3
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("DWebSecurityManager") DefaultWebSecurityManager DWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean ();
        shiroFilterFactoryBean.setSecurityManager (DWebSecurityManager);

        /**
         * Add Jmishiro's built-in filter step 3
         *
         * anon:Access without authentication
         * authc:You must be certified before you can ask
         * user:You must have the function of remembering me to use
         * perms:Only with the permission of the object resource can you access it;
         * role:You must have a role permission to access
         * */
        Map<String, String> configMap = new LinkedHashMap<> ();

        configMap.put ("/add", "perms[user:add]");
        //Authorization under normal circumstances, if you do not have permission, you will jump to the page without permission. Setting permission: perms[user:update]
        configMap.put ("/up", "perms[user:update]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap (configMap);
        //Set the request. If you don't have permission, go to the login page
        shiroFilterFactoryBean.setLoginUrl ("/toLogin");
        shiroFilterFactoryBean.setUnauthorizedUrl ("/noauth");
        return shiroFilterFactoryBean;
    }

    /**
     * * DafaultWebSecurityManager Step 2
     */
    @Bean(name = "DWebSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealms") UserRealm userRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager ();
        //Associating userRealm is particularly important
        defaultWebSecurityManager.setRealm (userRealm);


        return defaultWebSecurityManager;
    }

    /**
     * To create a realm object, you need to customize the class: Step 1
     *
     * @Bean(name = "userRealms")Attach a name to the method
     */
    @Bean(name = "userRealms")
    public UserRealm userRealm() {
        return new UserRealm ();
    }

    /**
     * Integrate ShiroDialect: used to integrate shiro thymeleaf
     */
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect ();
    }
}

  • UserRealm class (authorization and authentication of shrio)
package com.kuang.w.config;

import com.kuang.w.pojo.User;
import com.kuang.w.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.mgt.SecurityManager;
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;

import javax.security.sasl.AuthorizeCallback;

/**
 * @ClassName : UserRealm  //Class name
 * @Description : User defined class / / description
 * @Author : W //author
 * @Date: 2021/5/15  10:50
 */

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserServiceImpl userService;

    /**
     * 2 to grant authorization
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println ("Yes==>to grant authorization doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo ();

        //  subjectUser gets the object of the current user
        Subject subjectUser = SecurityUtils.getSubject ();
        //Get user object
        User principalUser = (User) subjectUser.getPrincipal ();

        //Permissions of the current user
        info.addStringPermission (principalUser.getPerms ());
        // **If there is no configuration, the return is null. If you want to return SimpleAuthorizationInfo | return null;
        return info;
    }

    /**
     * 1 First authentication
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println ("Yes==>authentication doGetAuthenticationInfo");

        /**
         *   Subject user
         *         SecurityManager Manage all users
         *         Realm Connection data*/
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        // Linked database
        // Call the userService method to query whether there are users
        User user = userService.queryUserByName (userToken.getUsername ());



     /*   if (!userToken.getUsername ().equals (user.getName ())) {
            return null;
            //Throw exception
        }*/
        if (user == null) {
            //Without this person
            return null;
            //Throw exception
        }
// The stored session value is used to determine whether to display the index login connection
        Subject subject = SecurityUtils.getSubject ();
        Session session = subject.getSession ();
        session.setAttribute ("loginUser", user);
//Password authentication
        return new SimpleAuthenticationInfo (user, user.getPassword (), "");
    }
}



-application.properties configuration

mybatis.type-aliases-package=com.kuang.w.pojo
mybatis.mapper-locations=classpath:mapper/*.xm

-application.yml

spring:
  datasource:
    username: root
    password: wj132199
    #? serverTimezone=UTC resolves the error in the time zone
    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 and needs to bind by itself
    #druid data source proprietary 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 filters for monitoring statistics interception, stat: monitoring statistics, log4j: logging, wall: defensive sql injection
    #If allowed, an error will be reported in Java lang.ClassNotFoundException: org. apache. log4j. Priority
    #Then import 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

end........

Keywords: Java MySQL Mybatis Shiro Spring

Added by rokchik on Thu, 10 Feb 2022 09:09:58 +0200