shiro教程二:spingboot整合shiro实现认证权限的管理。包括密码MD5+salt加密。以及缓存的设置。

shiro教程二:spingboot整合shiro实现认证权限的管理。包括密码MD5+salt加密。以及缓存的设置。

在shiro教程一中,我们已经知道了shiro框架的定义及简单上手,接下来我们就进入实战吧!
传送门:shiro教程一

关注公众号,文章会在公众号同步更新,谢谢大家关注!
在这里插入图片描述

首先附上项目的地址,欢迎大家下载和指导github项目地址
数据库表文件,在mapper文件夹下面哦!

1.数据库表的设计
首先是数据库的设计,该项目使用的是mysql8.0 ,用户的信息、用户的角色信息(你是管理员还是普通用户)、用户的权限信息(你具有哪些操作(增删改查或者其他功能。) ,那么问题来了, 数据库的表怎么设计呢 ? 很简单哒。先附图后说明:
在这里插入图片描述
我们设计了5张表,用户信息表,角色信息表,权限信息表、用户角色表、角色权限表。 首先是用户信息表,用户的注册登录信息从这里存储/取出。当用户要查你是哪个角色时。就根据用户角色表来;用户要查你有哪些权限时,就根据角色权限表来。

/*
MySQL Data Transfer
Source Host: localhost
Source Database: shiro
Target Host: localhost
Target Database: shiro
Date: 2021/1/16 11:23:32
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_pers
-- ----------------------------
DROP TABLE IF EXISTS `t_pers`;
CREATE TABLE `t_pers` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(60) NOT NULL,
  `url` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(60) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) NOT NULL,
  `password` varchar(40) NOT NULL,
  `salt` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_user_perms`;
CREATE TABLE `t_user_perms` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `roleid` int(10) NOT NULL,
  `permsid` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `userid` int(10) NOT NULL,
  `roleid` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records 
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', 'tom', '4980f486221eff4c6935d24bf41ccb96', 'bE!a4C!V');
INSERT INTO `t_user` VALUES ('2', 'lsg', 'a9286ead5cd36cfccbe0a56c10765ace', 'QFlNQ!7^');

2.代码上手

2.1 、项目结构图:
创建一个springboot应用。然后右击main,创建一个webapp文件夹。这里面放我们的页面。
(小提示:快速创建jsp页面:在创建的jsp空页面,中输入感叹号,然后按tab)
在这里插入图片描述

2.2、pom.xml文件。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1 </version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.znzz</groupId>
    <artifactId>springboot_jsp_shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_jsp_shiro</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!-- 加入shiro和ehcachae缓存-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- redis整合springboot,将缓存存入redis中-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--引入shiro整合的依赖 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.5.3</version>
        </dependency>


     <!--引入jsp解析的依赖-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.3、实体类 (entity中三个实体类。)

在这里插入图片描述

2.3.1、User.java(用户信息)

package com.znzz.springboot_jsp_shiro.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.List;

@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String username;
    private String password;
    private String salt;

    //定义一个角色集合
    private List<Role> roles;
}

2.3.2、Role.java(角色信息)

package com.znzz.springboot_jsp_shiro.entity;

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

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
    private String id;
    private String name;


    //定义一个权限的集合,因为权限时跟角色绑定的

    private List<Perms> perms;
}

2.3.3、Perms.java(权限信息表)

package com.znzz.springboot_jsp_shiro.entity;


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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Perms {
    private String id;
    private String name;
    private String url;

}

2.4、Dao层,(接口,提供方法。)
在这里插入图片描述

UserMapper.java

package com.znzz.springboot_jsp_shiro.mapper;


import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {

    void save(User user);

    User findByUserName(String username);

    //根据用户名查询角色
    User findRolesByUserName(String username);


    //根据角色的id获取到权限集合
    List<Perms> findPermsByRoleId(String id);


}

2.5、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.znzz.springboot_jsp_shiro.mapper.UserMapper">
     <insert id="save"  parameterType="User" keyProperty="id" useGeneratedKeys="true"  >
         insert into t_user values (#{id},#{username},#{password},#{salt})
    </insert>
    <select id="findByUserName" parameterType="String" resultType="User">

       select username,password,salt from t_user where username = #{username}

    </select>

    <resultMap id="userMap" type="User">
        <id column="uid" property="id"/>
        <result column="username" property="username"/>
        <!--角色信息 -->
        <collection property="roles" javaType="list" ofType="Role">
            <id column="id" property="id" />
            <result column="rname" property="name"/>
        </collection>

    </resultMap>

    <select id="findRolesByUserName" parameterType="String" resultMap="userMap">

     select u.id uid, u.username,r.id,r.NAME rname
     from t_user u
     LEFT JOIN t_user_role ur
     on u.id=ur.userid
     LEFT JOIN t_role r
     on ur.roleid=r.id
     WHERE u.username=#{username}

    </select>

    <select id="findPermsByRoleId" parameterType="String" resultType="Perms">
        select p.id , p.name , p.url , r.name from t_role r
        left join t_role_perms rp
        on r.id = rp.roleid
         left join t_perms p
          on rp.permsid = p.id
        where r.id = #{id}

    </select>



</mapper>

2.6、 application.properties 配置mysql连接,以及映射文件位置。

在这里插入图片描述

application.properties

server.servlet.context-path=/shiro
spring.application.name=shiro

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&userUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root

mybatis.type-aliases-package=com.znzz.springboot_jsp_shiro.entity
mybatis.mapper-locations=classpath:mapper/*.xml


logging.level.com.znzz.springboot_jsp_shiro.mapper=debug

2.7、业务层。
在这里插入图片描述

2.7.1、UserService.java

package com.znzz.springboot_jsp_shiro.service;

import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;

import java.util.List;

public interface UserService {
    void register(User user);

    User findByUserName(String username);

    //根据用户名查询角色

    User findRolesByUserName(String username);

    //根据角色的id获取到权限信息
  List<Perms> findPermsByRoleId(String id);



}

2.7.2、UserServiceImpl.java

package com.znzz.springboot_jsp_shiro.service;

import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.mapper.UserMapper;
import com.znzz.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;

import java.util.List;

@Service
@Transactional
public class UserServiceImpl implements UserService{
   @Autowired
   private UserMapper userMapper;

    @Override
    public void register(User user) {
        //处理业务
        //铭文的密码进行md5+ salt+ hash加密。
        //1.生成随机salt
        String salt = SaltUtils.getSalt(8)  ;
        user.setSalt(salt);
        Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);
        user.setPassword(md5Hash.toHex());
        userMapper.save(user);

    }

    @Override
    public User findByUserName(String username) {
        return userMapper.findByUserName(username);
    }


    //根据用户名查询角色
    @Override
    public User findRolesByUserName(String username) {


        return userMapper.findRolesByUserName(username);
    }


    //根据角色的id获取权限
    @Override
    public List<Perms> findPermsByRoleId(String id) {


        return userMapper.findPermsByRoleId(id);
    }
}

2.8、Controller层。

UserController.java

package com.znzz.springboot_jsp_shiro.controller;

import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;

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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {

      @Autowired
      private UserService userService;

    /**
     * 用来处理身份认证
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login")
     public String login(String username, String password,Model model){

        //获取主体对象
       Subject subject = SecurityUtils.getSubject();
       try {
           subject.login(new UsernamePasswordToken(username,password));
            return "redirect:/index.jsp";

       }catch (UnknownAccountException e){
            e.printStackTrace();
           System.out.println("用户名错误");
       }catch (IncorrectCredentialsException e){
           e.printStackTrace();
           System.out.println("密码错误");
       } catch (Exception 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";
}


/**
 * 用户注册校验
 */

@RequestMapping("/register")
public String register(User user){
try {
    userService.register(user);
    return "redirect:/login.jsp";
}catch (Exception e){
    e.printStackTrace();
    return "redirect:/register.jsp";
}

}

}

2.9.页面。

2.9.1、index.jsp(主页,登录成功之后的页面)

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>系统</title>
</head>
<body>
asdf

<ul>
    <li><a href=""></a>
    <ul>
        <shiro:hasPermission name="user:add:*">
            <li><a href="">增加一个</a></li>
        </shiro:hasPermission>


        <shiro:hasPermission name="user:update:*">
            <li><a href="">增加2</a></li>
        </shiro:hasPermission>
        <shiro:hasPermission name="user:select:*">
            <li><a href="">增加3</a></li>
        </shiro:hasPermission>
    </ul>

    </li>

    <shiro:hasRole name="admin">
    <li><a href=""></a></li>
    <li><a href=""></a></li>
    <li><a href=""></a></li>
    </shiro:hasRole>
</ul>

<br />
<br />
<br />
<br />
<hr />
<a href="${pageContext.request.contextPath}/user/logout">退出</a>

</body>
</html>

2.9.2、login.jsp(登录页面)

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登录</title>
</head>
<body>
登录界面

<p style="color: red">${msg}</p>
<form action="${pageContext.request.contextPath}/user/login" method="post">
  用户名:  <input type="text" name="username"> <br />
    密码:   <input type="text" name="password"> <br />
    验证码: <input type="text"> <img src=""alt="" /> <br />

   <input type="submit" value="提交">

</form>
</body>
</html>

2.9.3、register.jsp(注册页面)

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>注册</title>
</head>
<body>
注册界面

<form action="${pageContext.request.contextPath}/user/register" method="post">
  用户名:  <input type="text" name="username"> <br />
    密码:   <input type="text" name="password"> <br />
   <input type="submit" value="注册">

</form>
</body>
</html>

3.0、有关Realm的配置。
在这里插入图片描述
CustomerRealm.java

package com.znzz.springboot_jsp_shiro.shiro;


import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.service.UserService;
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.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


//自定义的realm的类
//用来进行数据校验
public class CustomerRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取身份信息
        String  primaryPrincipal =(String) principals.getPrimaryPrincipal();
        System.out.println("调用授权验证"+primaryPrincipal);
         //根据身份信息获取角色信息
        User user  =   userService.findRolesByUserName(primaryPrincipal);
        System.out.println(userService.findRolesByUserName(primaryPrincipal));
       //角色不为空,构建角色信息
        //授权角色信息
        if(!CollectionUtils.isEmpty(user.getRoles())){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            user.getRoles().forEach(role -> {
                simpleAuthorizationInfo.addRole(role.getName());
                System.out.println("=========");
                System.out.println("用户的角色:"+role.getName());
                //角色遍历出来了,现在还需要权限。
                List<Perms> perms = userService.findPermsByRoleId(role.getId());
                if(!CollectionUtils.isEmpty(perms)){
                    perms.forEach(perm -> {
                        //添加权限信息
                        simpleAuthorizationInfo.addStringPermission(perm.getName());
                        System.out.println("=========");
                        System.out.println("用户的权限:"+perm.getName());
                    });
                }
            });
         return simpleAuthorizationInfo;
        }


        return null;
    }


    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("=======================");

        String principal = (String) token.getPrincipal();

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
       //获取身份信息
        User userName = userService.findByUserName(userToken.getUsername());
        System.out.println("密码:==========="+ userName.getPassword());
        System.out.println("用户名:=============="+userName.getUsername());

        if (userName != null){
            return new SimpleAuthenticationInfo(userName.getUsername(),userName.getPassword(), ByteSource.Util.bytes(userName.getSalt()),this.getName());
        }

        return null;

    }
}

3.1、shiro的配置。

package com.znzz.springboot_jsp_shiro.config;


import com.znzz.springboot_jsp_shiro.shiro.CustomerRealm;
import com.znzz.springboot_jsp_shiro.shiro.RedisCacheManager;
import lombok.val;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.management.MXBean;
import java.util.HashMap;
import java.util.Map;

/**
 * 用来整合shiro的配置类
 */
@Configuration
public class ShiroConfig {
      //1.创建shiroFilter
      //负责拦截所有请求

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
     ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
     //给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
   //配置系统的受限资源
        Map<String, String> map = new HashMap<String, String>();
        map.put("/index.jsp","authc");//authc表示访问这个资源需要认证和授权
        map.put("/user/register","anon");
        map.put("/register.jsp","anon");//anon表示公共资源,都可以访问的到。
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        //配置系统的公共资源

        //默认认证的界面路径,(及你访问没有权限的页面时,会跳转到该页面。)就算你不配置,也会跳转到这个login页面。
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");




      return shiroFilterFactoryBean;
    }
      //2.创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(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);

       //开启缓存管理
       //shiro默认的缓存管理器,你也可以存入redis中。该项目没有
      customerRealm.setCacheManager(new EhCacheManager());


      customerRealm.setCachingEnabled(true);// 开启全局缓存
      customerRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
      customerRealm.setAuthenticationCacheName("authentication");
      customerRealm.setAuthorizationCachingEnabled(true);
      customerRealm.setAuthorizationCacheName("authorization");//开启授权的缓存
        return customerRealm;
}

}

3.2、密码加密工具类
在这里插入图片描述
SaltUtils.java

package com.znzz.springboot_jsp_shiro.utils;

import java.util.Random;
import java.util.UUID;

public class SaltUtils {


    /**
     *
     * 随机生成salt
     * @param
     */
    public static String getSalt( int n){
         char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabvdefghijklmnopqrstuvwxyz!@#$%^&*012345679".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();
    }


完成之后运行调试一下吧。

(1).访问 http://localhost:8080/shiro/index.jsp, 他会自动跳转到登录界面。因为我们给index.jsp这个路径设置了必须要认证才能访问哦!
(2).输入用户名:lsg ;密码: 123 ,登录,你就会发现登录成功,进入index.jsp页面,你能够看到这些东西,是因为你有管理员的权限,(可到数据库自己查看),
在这里插入图片描述

(3)…输入用户名:tom;密码: 123 ,登录,你就会发现登录成功,进入index.jsp页面,你能够看到这些东西,是因为你只有用户的权限,(可到数据库自己查看),
在这里插入图片描述

另外,在shiro中加了缓存,你会发现,你一直刷新index.jsp页面。控制台不会输出任何东西,(先说名一下,如果你不开启缓存,你每次刷新都会查询数据库,用户的每次权限,角色都会查数据库,导致压力很大,所以才加入缓存。)这是因为我们开启了缓存,只是第一次用户进入系统的时候才会查询数据库,以后就直接查缓存。

最后,如果有不懂的,请查看教程一,shiro教程一地址

如果有错请及时指出,谢谢大家。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值