117. Shiro (2): SpringBoot integrates Shiro (1): Set up the environment and complete the authentication module

In actual combat, for the convenience of the front-end, we directly use jsp as the front-end. Take Vue as an example when you really integrate the project.

1. Setting up the environment

1. Create a project

After creating, delete the unused files:

2. Integrate jsp

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><html><head>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <title>xupeng</title></head><body>    hello world</body></html>

3. Configuration file application.properties

Set the port, path, and prefix suffix

server.port=8888server.servlet.context-path=/shirospring.application.name=shiro spring.mvc.view.prefix=/spring.mvc.view.suffix=.jsp

4.pom.xml add dependency

<!--引入jsp依赖-->        <dependency>            <groupId>org.apache.tomcat.embed</groupId>            <artifactId>tomcat-embed-jasper</artifactId>            <version>9.0.45</version>        </dependency>         <dependency>            <groupId>jstl</groupId>            <artifactId>jstl</artifactId>            <version>1.2</version>        </dependency>        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>servlet-api</artifactId>            <version>2.5</version>        </dependency>

5. Test

We can directly succeed:

If you cannot succeed, you need Edit Configurations in the upper right corner:

Then the test can be successful.

2. Integrate shiro into springboot

1. Introduce dependencies

We have introduced JSP-related dependencies above, here are some shiro-related dependencies:

2. Edit index.jsp and login.jsp

The hello world of our index.jsp has been successful just now, now we will change it a little bit

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><html><head>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <title>xupeng</title></head><body>    <h1>首页</h1> <ul>    <li><a href="">用户管理</a></li>    <li><a href="">商品管理</a></li>    <li><a href="">订单管理</a></li>    <li><a href="">物流管理</a></li></ul></body></html>

login.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><html><head>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <title>xupeng</title></head><body>    <h1>登录页</h1></body></html>

3. Edit CunstomerRealm

Create a new CunstomerRealm, the role of this class is mainly used for authentication and authorization:

package com.xupeng.springboot_jsp_shiro.shiro.realms; /** * [一句话描述该类的功能] * * @author : [xupeng] * @version : [v1.0] * @createTime : [2021/5/31 9:22] */ import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection; /** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm {	@Override	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {		return null;	} 	@Override	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {		return null;	}} 

4. Edit ShiroConfig

package com.xupeng.springboot_jsp_shiro.config; import com.xupeng.springboot_jsp_shiro.shiro.realms.CustomerRealm;import org.apache.shiro.realm.Realm;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.HashMap;import java.util.Map; /** * 用来整合shiro框架相关的配置类 */@Configurationpublic class ShiroConfig {    //1.创建shiroFilter    @Bean    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();         //给filter设置安全管理器        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);         //配置系统受限资源        //配置系统公共资源        Map<String,String> map = new HashMap<>();        map.put("/index.jsp","authc");//authc 请求这个资源需要认证和授权        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);         //默认认证界面路径        //如果不写,也是默认/login.jsp        shiroFilterFactoryBean.setLoginUrl("/login.jsp");         return shiroFilterFactoryBean;    }    //2.创建安全管理器    @Bean    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();         //给安全管理器设置realm        defaultWebSecurityManager.setRealm(realm);         return  defaultWebSecurityManager;    }     //3.创建自定义的realm    @Bean    public Realm getRealm(){        CustomerRealm customerRealm = new CustomerRealm();        return customerRealm;    }}

5. Test

When we enter index.jsp, it will automatically jump into login.jsp, because we set index.jsp to be verified, and the default jump is login.jsp, and our setting happens to be login.jsp. In fact, we will still do if we don’t set it. Jump into login.jsp, so:

Three, common filters

Here is a mouthful, the so-called filter here actually corresponds to the authc in our ShiroConfig.

In fact, in addition to authc, there are other filters with other functions, let's take a look:

Configuration abbreviationRight filterFeatures
anonAnonymousFilterThe specified URL can be accessed anonymously, that is, it is public and does not need to be verified
authcFormAuthenticationFilterThe specified url requires form login.
Get username, password and other parameters by default, if you can’t log in, it will jump to the path configured by loginUrl
authcBasicBasicHttpAuthenticationFilterSpecify url requires basic login
logoutLogoutFilterLogout filter
noSessionCreationNoSessionCreationFilterDisallow session creation
permsPermissionsAuthorizationFilterNeed to specify permissions to access
portPortFilterNeed to specify the port to access
restHttpMethodPermissionFilterConverting the http request method to the corresponding verb to construct a permission string is useless
rolesRolesAuthorizationFilterNeed to assign a role to access
sslSslFilterRequires https request to access
userUserFilterRequires logged in or "remember me" users to access

4. Realization of Shiro login and logout function

We need to modify these four categories:

1. Edit index.jsp

Add a logout button to the homepage

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><html><head>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <title>xupeng</title></head><body>    <h1>首页</h1>    <a href="${ pageContext.request.contextPath}/user/logout">退出登录</a><ul>    <li><a href="">用户管理</a></li>    <li><a href="">商品管理</a></li>    <li><a href="">订单管理</a></li>    <li><a href="">物流管理</a></li></ul></body></html>

2.login.jsp

Add a login button to the login page

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><html><head>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <title>xupeng</title></head><body>    <h1>登录页</h1>     <form action="${pageContext.request.contextPath}/user/login" method="post">        用户名:<input type="text" name="username"/>        密码:<input type="password" name="password"/>        <input type="submit" value="登录"/>     </form></body></html>

3.CustomerRealm

In Realm, some settings are made for the authentication user name, here it is only verified in plain text for the time being:

package com.xupeng.springboot_jsp_shiro.shiro.realms; import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection; /** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm {    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        return null;    }     @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        System.out.println("---------------------------");        String principal = (String) authenticationToken.getPrincipal();        if("xupeng".equals(principal)){            return new SimpleAuthenticationInfo(principal,"456",this.getName());        }        return null;    }}

4.ShiroConfig

Set some filter conditions to make the login function public, and other settings require authentication and authorization:

package com.xupeng.springboot_jsp_shiro.config; import com.xupeng.springboot_jsp_shiro.shiro.realms.CustomerRealm;import org.apache.shiro.realm.Realm;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.HashMap;import java.util.Map; /** * 用来整合shiro框架相关的配置类 */@Configurationpublic class ShiroConfig {    //1.创建shiroFilter    @Bean    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();         //给filter设置安全管理器        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);         //配置系统受限资源        //配置系统公共资源        Map<String,String> map = new HashMap<>();        map.put("/user/login","anon");//anon 设置为公共资源        map.put("/**","authc");//authc 请求这个资源需要认证和授权        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);         //默认认证界面路径        //如果不写,也是默认/login.jsp        shiroFilterFactoryBean.setLoginUrl("/login.jsp");         return shiroFilterFactoryBean;    }    //2.创建安全管理器    @Bean    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();         //给安全管理器设置realm        defaultWebSecurityManager.setRealm(realm);         return  defaultWebSecurityManager;    }     //3.创建自定义的realm    @Bean    public Realm getRealm(){        CustomerRealm customerRealm = new CustomerRealm();        return customerRealm;    }}

5.UserController

Write the login and logout controller

package com.xupeng.springboot_jsp_shiro.controller; import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping; @[email protected]("user")public class UserController {     /**     * 用来处理身份认证     */    @RequestMapping("login")    public String login(String username,String password){        //获取主体对象        Subject subject = SecurityUtils.getSubject();        try {            subject.login(new UsernamePasswordToken(username,password));            return "redirect:/index.jsp";        }catch (UnsupportedOperationException e){            e.printStackTrace();            System.out.println("用户名错误");        }catch (IncorrectCredentialsException e){            e.printStackTrace();            System.out.println("密码错误");        }        return "redirect:/login.jsp";    }     /**     * 退出登录     */    @RequestMapping("logout")    public String logout(){        Subject subject = SecurityUtils.getSubject();        subject.logout();        return "redirect:/login.jsp";    }}

6. Test

5. Shiro connects to the database and completes the registration function based on MD5+Salt+Hash

First look at the directory structure:

1. First create a simple database table

CREATE TABLE `t_user` (  `id` int NOT NULL AUTO_INCREMENT,  `username` varchar(40) COLLATE utf8mb4_general_ci DEFAULT NULL,  `password` varchar(40) COLLATE utf8mb4_general_ci DEFAULT NULL,  `salt` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
 <!--引入mybatis依赖-->        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>            <version>2.1.2</version>        </dependency>         <!--引入mysql依赖-->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>8.0.18</version>        </dependency> <!--引入druid依赖-->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>1.1.19</version>        </dependency>

3. Configure application.properties

Add database and mybatis related configuration:

server.port=8888server.servlet.context-path=/shirospring.application.name=shiro spring.mvc.view.prefix=/spring.mvc.view.suffix=.jsp spring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=UTF-8&serverTimezone=UTCspring.datasource.username=rootspring.datasource.password=xp880000 mybatis.type-aliases-package=com.xupeng.springboot_jsp_shiro.entitymybatis.mapper-locations=classpath:mapper/*.xml

4. Create the entity layer code


It should be noted here that our entity uses lombok. If your idea is not downloaded, download it. After downloading, restart it:

User

package com.xupeng.springboot_jsp_shiro.entity; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.experimental.Accessors; @[email protected]@[email protected](chain = true)public class User {    private String id;    private String username;    private String password;    private String salt;}

5. Write the dao layer

UserDao

package com.xupeng.springboot_jsp_shiro.dao; import com.xupeng.springboot_jsp_shiro.entity.User;import org.apache.ibatis.annotations.Mapper; @Mapperpublic interface UserDao {    void save(User user);}

UserDaoMapper.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.xupeng.springboot_jsp_shiro.dao.UserDao">    <insert id="save" parameterType="User" >        insert into t_user values  (#{id},#{username},#{password},#{salt})    </insert>  </mapper>

6. Writing tools

Write a tool class to generate random salt

SaltUtils

package com.xupeng.springboot_jsp_shiro.utils; import java.util.Random; public class SaltUtils {    public static String getSalt(int n) {        char[] chars = "[email protected]#$%^&*()".toCharArray();        StringBuilder sb = new StringBuilder();        for(int i = 0;i<n;i++){            char aChar = chars[new Random().nextInt(chars.length)];            sb.append(aChar);        }        return sb.toString();    }     public static void main(String[] args) {        String salt = getSalt(4);        System.out.println(salt);    }}

7. Write the service layer

UserService:

package com.xupeng.springboot_jsp_shiro.service; import com.xupeng.springboot_jsp_shiro.entity.User; public interface UserService {    void register(User user);}

UserServiceImpl:

package com.xupeng.springboot_jsp_shiro.service.impl; import com.xupeng.springboot_jsp_shiro.dao.UserDao;import com.xupeng.springboot_jsp_shiro.entity.User;import com.xupeng.springboot_jsp_shiro.service.UserService;import com.xupeng.springboot_jsp_shiro.utils.SaltUtils;import org.apache.shiro.crypto.hash.Md5Hash;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional; @[email protected] class UserServiceImpl implements UserService {    @Autowired    private UserDao userDao;     @Override    public void register(User user) {        //明文密码进行md5+salt+hash散列        //1.生成随机盐        String salt = SaltUtils.getSalt(8);        //2.将随机盐保存到数据        user.setSalt(salt);        //3.明文密码进行md5+salt+hash散列        Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);        user.setPassword(md5Hash.toHex());         userDao.save(user);    }}

8. Write the controller layer

package com.xupeng.springboot_jsp_shiro.controller; import com.xupeng.springboot_jsp_shiro.entity.User;import com.xupeng.springboot_jsp_shiro.service.UserService;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping; @[email protected]("user")public class UserController {    @Autowired    private UserService userService;     /**     * 用户认证     */    @RequestMapping("register")    public String register(User user){        try {            userService.register(user);            return "redirect:/login.jsp";        }catch (Exception e){            e.printStackTrace();            return "redirect:/register.jsp";        }    }     /**     * 用来处理身份认证     */    @RequestMapping("login")    public String login(String username,String password){        //获取主体对象        Subject subject = SecurityUtils.getSubject();        try {            subject.login(new UsernamePasswordToken(username,password));            return "redirect:/index.jsp";        }catch (UnsupportedOperationException e){            e.printStackTrace();            System.out.println("用户名错误");        }catch (IncorrectCredentialsException e){            e.printStackTrace();            System.out.println("密码错误");        }        return "redirect:/login.jsp";    }     /**     * 退出登录     */    @RequestMapping("logout")    public String logout(){        Subject subject = SecurityUtils.getSubject();        subject.logout();        return "redirect:/login.jsp";    }}

9. Test

So far, our test has been successful

6. Complete the authentication function based on MD5+salt

As of now, the authentication is still a string that is hard-coded in the code. We now need to modify the authentication function according to the content of the database.

Because we have added a new class, post the package path:

1. Modify the dao layer

UserDao:

@Mapperpublic interface UserDao {    void save(User user);     User fingByUsername(String username);}

UserDaoMapper.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.xupeng.springboot_jsp_shiro.dao.UserDao">    <insert id="save" parameterType="User" >        insert into t_user values  (#{id},#{username},#{password},#{salt})    </insert>     <select id="fingByUsername" parameterType="String" resultType="User">        select id,username,password,salt from t_user where username = #{username}    </select></mapper>

2. Modify the service layer

UserService:

package com.xupeng.springboot_jsp_shiro.service; import com.xupeng.springboot_jsp_shiro.entity.User; public interface UserService {    void register(User user);     User fingByUsername(String username);}

UserServiceImpl:

We named the service method here. The reason for this is that we will create a new instance through the factory design pattern: create a new tool class to generate the ApplicationContext, and then rewrite the getBean method to obtain the object.

package com.xupeng.springboot_jsp_shiro.service.impl; import com.xupeng.springboot_jsp_shiro.dao.UserDao;import com.xupeng.springboot_jsp_shiro.entity.User;import com.xupeng.springboot_jsp_shiro.service.UserService;import com.xupeng.springboot_jsp_shiro.utils.SaltUtils;import org.apache.shiro.crypto.hash.Md5Hash;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional; @Service("userService")@Transactionalpublic class UserServiceImpl implements UserService {    @Autowired    private UserDao userDao;     @Override    public void register(User user) {        //明文密码进行md5+salt+hash散列        //1.生成随机盐        String salt = SaltUtils.getSalt(8);        //2.将随机盐保存到数据        user.setSalt(salt);        //3.明文密码进行md5+salt+hash散列        Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);        user.setPassword(md5Hash.toHex());         userDao.save(user);    }     @Override    public User fingByUsername(String username) {        return userDao.fingByUsername(username);    }}

3. New ApplicationContextUtils

Create a new instance of the factory design pattern to maintain the independence of the code:

package com.xupeng.springboot_jsp_shiro.utils; import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component; @Componentpublic class ApplicationContextUtils implements ApplicationContextAware {    private static ApplicationContext applicationContext;     @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        this.applicationContext = applicationContext;    }     //根据bean名字获取工厂中指定bean对象    public static Object getBean(String beanName) {        return applicationContext.getBean(beanName);    }}

4. Modify ShiroConfig

ShiroConfig :

It used to be the simplest username and password matching, now we replace the credential verification matcher to match the username and the salted hash password

package com.xupeng.springboot_jsp_shiro.config; import com.xupeng.springboot_jsp_shiro.shiro.realms.CustomerRealm;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.realm.Realm;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.HashMap;import java.util.Map; /** * 用来整合shiro框架相关的配置类 */@Configurationpublic class ShiroConfig {    //1.创建shiroFilter    @Bean    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();         //给filter设置安全管理器        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);         //配置系统受限资源        //配置系统公共资源        Map<String,String> map = new HashMap<>();        map.put("/user/login","anon");//anon 设置为公共资源        map.put("/user/register","anon");//anon 设置为公共资源        map.put("/register.jsp","anon");//anon 设置为公共资源        map.put("/**","authc");//authc 请求这个资源需要认证和授权        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);         //默认认证界面路径        //如果不写,也是默认/login.jsp        shiroFilterFactoryBean.setLoginUrl("/login.jsp");         return shiroFilterFactoryBean;    }    //2.创建安全管理器    @Bean    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();         //给安全管理器设置realm        defaultWebSecurityManager.setRealm(realm);         return  defaultWebSecurityManager;    }     //3.创建自定义的realm    @Bean    public Realm getRealm(){        CustomerRealm customerRealm = new CustomerRealm();         //修改凭证校验匹配器        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();        //设置加密算法为md5        credentialsMatcher.setHashAlgorithmName("MD5");        //设置散列次数        credentialsMatcher.setHashIterations(1024);        customerRealm.setCredentialsMatcher(credentialsMatcher);        return customerRealm;    }}

5. Modify CustomerRealm

Change the original hard-coded authentication into authentication based on the user name and password passed in and compare the database data:

package com.xupeng.springboot_jsp_shiro.shiro.realms; import com.xupeng.springboot_jsp_shiro.entity.User;import com.xupeng.springboot_jsp_shiro.service.UserService;import com.xupeng.springboot_jsp_shiro.utils.ApplicationContextUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.util.ObjectUtils; /** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm {    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        return null;    }     @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        System.out.println("---------------------------");         //获取身份信息        String principal = (String) authenticationToken.getPrincipal();         //在工厂中获取service对象        UserService userService = (UserService) ApplicationContextUtils.getBean("userService");        User user = userService.fingByUsername(principal);         if (!ObjectUtils.isEmpty(user)) {            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());        }        return null;    }}

6. Edit the configuration file

Add a log:

logging.level.com.xupeng.springboot_jsp_shiro.dao=debug

7. Test

Seven, reward request

If this blog is helpful to you, I would like to give you a reward, thank you~