六、Spring Boot整合Shiro

  • 6.1、整合思路
  • 6.2、创建spring boot项目
  • 6.3、引入shiro依赖
  • 6.4、配置shiro环境
    • 创建配置类ShiroConfig
      • 1.配置:shiroFilterFactoryBean
      • 2.配置WebSecurityManager
      • 3.配置自定义Relam
      • ShiroConfig
    • 配置自定义Realm
      • CustomerRealm
  • 6.5、常见过滤器
  • 6.6、认证和退出
    • 修改UserController
    • 修改ShiroConfig
    • 修改login.jsp
    • 修改index.jsp
    • 修改CustomerRealm
  • 6.7、数据库注册和认证
    • 注册
      • 新建表
      • 添加依赖pom
      • 配置application.properties
      • 新建SaltUtils
      • 新建UserController
      • 新建UserServiceImpl
      • 新建register.jsp
      • 新建UserDAOMapper.xml
    • 认证
      • 修改UserDAO
      • 修改UserService
      • 修改UserServiceImpl
      • 修改CustomerRealm
      • 修改UserDAOMapper.xml
      • 修改ShiroConfig
  • 6.8、授权
    • 基本使用
      • 修改index.jsp
      • 修改CustomerRealm
      • 测试
      • 修改CustomerRealm
      • 修改index.jsp
      • 测试
      • 测试2
      • 测试3
        • 修改index.jsp
        • 修改CustomerRealm
    • 演示订单添加校验
      • 角色校验
        • 添加orderController
      • 权限字符串
        • 修改CustomerRealm
        • 修改orderController
    • 角色信息数据库获取
      • shiro数据库
      • 新建表
        • t_role
        • t_pers
        • t_role_perms
        • t_user_role
      • 新建Role
      • 新建Perms
      • 修改User
      • 修改UserDAO
      • 修改UserDAOMapper.xml
      • 测试SQL
      • 修改UserService
      • 修改UserServiceImpl
      • 修改CustomerRealm
      • 测试
    • 权限信息数据库获取
      • 修改Role
      • 修改t_pers
      • 修改t_role_perms
      • 修改UserService
      • 修改UserServiceImpl
      • 修改CustomerRealm
      • 修改UserDAOMapper.xml
      • 修改index.jsp
      • 测试
        • xiaochen
        • zhangsan

6.1、整合思路

6.2、创建spring boot项目

main下新建webapp目录

6.3、引入shiro依赖

 <!--引入Shiro依赖--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.5.3</version></dependency>

6.4、配置shiro环境

创建配置类ShiroConfig

1.配置:shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {//创建shiro的filterShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//给filter设置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}
2.配置WebSecurityManager
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//给安全管理器设置defaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}
3.配置自定义Relam
@Beanpublic Realm getRealm() {CustomerRealm customerRealm = new CustomerRealm();return customerRealm;}
ShiroConfig
package com.hz52.springboot_jsp_shiro.config;import com.hz52.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** @Program: springboot_jsp_shiro* @Description: 用来整合shiro相关配置类* @Author: 52Hz* @CreationTime: 2021年10月20日 9:18 星期三**/@Configuration
public class ShiroConfig {//1、shiroFilter //负责拦截所有请求(依赖2)@Beanpublic 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请求这个资源需要认证和授权shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//默认认证界面路径shiroFilterFactoryBean.setLoginUrl("/login.jsp");//配置系统公共资源return shiroFilterFactoryBean;}//2、创建安全管理器(依赖3)@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//给安全管理器设置defaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3、创建自定义realm(依赖Realms里面的自定义realm)@Beanpublic Realm getRealm() {CustomerRealm customerRealm = new CustomerRealm();return customerRealm;}}

配置自定义Realm

CustomerRealm
package com.hz52.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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {return null;}
}

6.5、常见过滤器

Shiro提供多个默认的过滤器,我们可以用这些过滤器来配置控制指定URL的权限,Shiro常见的过滤器如下:

配置缩写 对应的过滤器 功能
身份验证相关的
anon AnonymousFilter 指定url可以匿名访问
authc FormAuthenticationFilter 基于表单的拦截器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录;主要属性:usernameParam:表单提交的用户名参数名( username); passwordParam:表单提交的密码参数名(password); rememberMeParam:表单提交的密码参数名(rememberMe); loginUrl:登录页面地址(/login.jsp);successUrl:登录成功后的默认重定向地址; failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure)
authcBasic BasicHttpAuthenticationFilter Basic HTTP身份验证拦截器,主要属性: applicationName:弹出登录框显示的信息(application)
logout authc.LogoutFilter 退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/)
user UserFilter 用户拦截器,用户已经身份验证/记住我登录的都可
授权相关的
roles RolesAuthorizationFilter 角色授权拦截器,验证用户是否拥有所有角色;主要属性: loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]”
perms PermissionsAuthorizationFilter 权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例“/user/**=perms[“user:create”]”
port PortFilter 端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
rest HttpMethodPermissionFilter rest风格拦截器,自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll)
ssl SslFilter SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样
noSessionCreation NoSessionCreationAuthorizationFilter 需要指定权限才能访问

6.6、认证和退出

修改UserController

package com.hz52.springboot_jsp_shiro.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.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月20日 14:13 星期三**/
@Controller
@RequestMapping("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 (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名出错");} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误");}return "redirect:/login.jsp";}@RequestMapping("logout")public String logout(String username, String password) {//获取主体对象Subject subject = SecurityUtils.getSubject();subject.logout();return "redirect:/login.jsp";}}

修改ShiroConfig

package com.hz52.springboot_jsp_shiro.config;import com.hz52.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** @Program: springboot_jsp_shiro* @Description: 用来整合shiro相关配置类* @Author: 52Hz* @CreationTime: 2021年10月20日 9:18 星期三**/@Configuration
public class ShiroConfig {//1、shiroFilter //负责拦截所有请求(依赖2)@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//给filter设置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//配置系统受限资源Map<String, String> map = new HashMap<String, String>();map.put("/user/login","anon");   //anon设置为公共资源map.put("/**", "authc");  //authc请求这个资源需要认证和授权shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//默认认证界面路径shiroFilterFactoryBean.setLoginUrl("/login.jsp");//配置系统公共资源return shiroFilterFactoryBean;}//2、创建安全管理器(依赖3)@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//给安全管理器设置defaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3、创建自定义realm(依赖Realms里面的自定义realm)@Beanpublic Realm getRealm() {CustomerRealm customerRealm = new CustomerRealm();return customerRealm;}}

修改login.jsp

<%@page contentType="text/html; UTF-8%" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>用户登录</h1><form action="${pageContext.request.contextPath}/user/login" method="post">用户名:<input type="text" name="username"><br/>密码:<input type="text" name="password"><br/><input type="submit" value="登录">
</form></body>
</html>

修改index.jsp

<%@page contentType="text/html; UTF-8%" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>系统主页V1.0</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>

修改CustomerRealm

package com.hz52.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;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("===================");String principal = (String) token.getPrincipal();if ("xiaochen".equals(principal)) {return new SimpleAuthenticationInfo(principal,"123",this.getName());}return null;}
}

6.7、数据库注册和认证

注册

新建表

添加依赖pom
     <!--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>5.1.38</version></dependency><!--druid依赖--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.19</version></dependency>
配置application.properties
server.port=8080
server.servlet.context-path=/shiro
spring.application.name=shirospring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp######Druid监控配置######
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
#dataSource Pool configuration
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.exceptionSorter=true
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.filters=stat,wall,log4j
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
spring.datasource.useGlobalDataSourceStat=truemybatis.type-aliases-package=com.hz52.springboot_jsp_shiro.entity
mybatis.mapper-locations=classpath:com/hz52/mapper/*.xml
新建SaltUtils

package com.hz52.Utils;import java.util.Random;/*** @Program: springboot_jsp_shiro* @Description: 生成salt的静态方法:传入几位返回几位* @Author: 52Hz* @CreationTime: 2021年10月22日 10:19 星期五**/
public class SaltUtils {public static String getSalt(int n) {char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()".toCharArray();StringBuffer sb = new StringBuffer();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) {System.out.println(getSalt(32));}}
新建UserController
package com.hz52.springboot_jsp_shiro.controller;import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月20日 14:13 星期三**/
@Controller
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;@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 (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名出错");} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误");}return "redirect:/login.jsp";}@RequestMapping("logout")public String logout(String username, String password) {//获取主体对象Subject subject = SecurityUtils.getSubject();subject.logout();return "redirect:/login.jsp";}/*** @Description: 用户注册* @Author: 52Hz* @Date: 2021/10/22* @Time: 15:29*/@RequestMapping("register")public String register(User user) {try {userService.register(user);return "redirect:/login.jsp";} catch (Exception e) {e.printStackTrace();return "redirect:/register.jsp";}}}
新建UserServiceImpl
package com.hz52.springboot_jsp_shiro.service.impl;import com.hz52.Utils.SaltUtils;
import com.hz52.springboot_jsp_shiro.dao.UserDAO;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:14 星期五**/
@Service
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void register(User user) {//处理业务调用DAO//明文密码进行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);}
}
新建register.jsp
<%@page contentType="text/html; UTF-8%" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>用户注册</h1><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>
新建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.hz52.springboot_jsp_shiro.dao.UserDAO"><insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_uservalues (#{id}, #{username}, #{password}, #{salt})</insert></mapper>

认证

修改UserDAO
package com.hz52.springboot_jsp_shiro.dao;import com.hz52.springboot_jsp_shiro.entity.User;
import org.apache.ibatis.annotations.Mapper;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月20日 17:27 星期三**/
@Mapper
public interface UserDAO {void save(User user);User findByUserName(String username);
}
修改UserService
package com.hz52.springboot_jsp_shiro.service;import com.hz52.springboot_jsp_shiro.entity.User;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:13 星期五**/
public interface UserService {//代表注册用户void register(User user);User findByUserName(String username);}
修改UserServiceImpl
package com.hz52.springboot_jsp_shiro.service.impl;import com.hz52.Utils.SaltUtils;
import com.hz52.springboot_jsp_shiro.dao.UserDAO;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:14 星期五**/
@Service
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void register(User user) {//处理业务调用DAO//明文密码进行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);}@Overridepublic User findByUserName(String username) {return userDAO.findByUserName(username);}
}
修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.context.ApplicationContext;
import org.springframework.util.ObjectUtils;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
修改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.hz52.springboot_jsp_shiro.dao.UserDAO"><insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_uservalues (#{id}, #{username}, #{password}, #{salt})</insert><select id="findByUserName" resultType="User" parameterType="String">select id, username,password, saltfrom t_userwhere username = #{username}</select></mapper>
修改ShiroConfig
package com.hz52.springboot_jsp_shiro.config;import com.hz52.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** @Program: springboot_jsp_shiro* @Description: 用来整合shiro相关配置类* @Author: 52Hz* @CreationTime: 2021年10月20日 9:18 星期三**/@Configuration
public class ShiroConfig {//1、shiroFilter //负责拦截所有请求(依赖2)@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//给filter设置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//配置系统受限资源Map<String, String> map = new HashMap<String, String>();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);//默认认证界面路径shiroFilterFactoryBean.setLoginUrl("/login.jsp");//配置系统公共资源return shiroFilterFactoryBean;}//2、创建安全管理器(依赖3)@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//给安全管理器设置defaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3、创建自定义realm(依赖Realms里面的自定义realm)@Beanpublic Realm getRealm() {CustomerRealm customerRealm = new CustomerRealm();//修改密码匹配器:默认最简单HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//设置加密算法为md5credentialsMatcher.setHashAlgorithmName("md5");//设置散列次数credentialsMatcher.setHashIterations(1024);customerRealm.setCredentialsMatcher(credentialsMatcher);return customerRealm;}}

6.8、授权

基本使用

修改index.jsp

添加标签

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>单一角色标签<shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole>多角色标签<shiro:hasAnyRoles name="user,admin"><li><a href="">用户管理</a></li></shiro:hasAnyRoles>
<%@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 http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>系统主页V1.0</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a><ul><li><a href="">用户管理</a></li><shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole></ul></body>
</html>
修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();//根据主身份信息获取角色信息和权限信息if ("xiaochen".equals(primaryPrincipal)) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.addRole("user");return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
测试

修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();//根据主身份信息获取角色信息和权限信息if ("xiaochen".equals(primaryPrincipal)) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.addRole("admin");return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
修改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 http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>系统主页V1.0</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a><ul><shiro:hasAnyRoles name="user,admin"><li><a href="">用户管理</a></li></shiro:hasAnyRoles><shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole></ul></body>
</html>
测试

测试2

测试3

修改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 http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>系统主页V1.0</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a><ul><shiro:hasAnyRoles name="user,admin"><li><a href="">用户管理</a></li><ul><shiro:hasPermission name="user:add:*"><li><a href="">添加</a></li></shiro:hasPermission><shiro:hasPermission name="user:delete:*"><li><a href="">删除</a></li></shiro:hasPermission><shiro:hasPermission name="user:update:*"><li><a href="">修改</a></li></shiro:hasPermission><shiro:hasPermission name="user:find:*"><li><a href="">查询</a></li></shiro:hasPermission></ul></shiro:hasAnyRoles><shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole></ul></body>
</html>
修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();//根据主身份信息获取角色信息和权限信息if ("xiaochen".equals(primaryPrincipal)) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//添加角色simpleAuthorizationInfo.addRole("user");//添加角色字符串simpleAuthorizationInfo.addStringPermission("user:*:*");return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}

演示订单添加校验

角色校验

添加orderController

package com.hz52.springboot_jsp_shiro.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月23日 9:47 星期六**/
@Controller
@RequestMapping("order")
public class orderController {//方式三:注解@RequiresRoles(value = {"admin","user"})    //用来判断角色@RequestMapping("save")public String save() {System.out.println("进入方法");//获取主体对象Subject subject = SecurityUtils.getSubject();//方式一:代码方式if (subject.hasRole("admin")) {System.out.println("保存订单");} else {System.out.println("无权访问");}//方式二:基于权限字符串...return "redirect:/index.jsp";}}
权限字符串
修改CustomerRealm

package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();//根据主身份信息获取角色信息和权限信息if ("xiaochen".equals(primaryPrincipal)) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//添加角色simpleAuthorizationInfo.addRole("admin");simpleAuthorizationInfo.addRole("user");//添加角色字符串// simpleAuthorizationInfo.addStringPermission("user:*:*");simpleAuthorizationInfo.addStringPermission("user:add:*");simpleAuthorizationInfo.addStringPermission("user:update:01");return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
修改orderController

package com.hz52.springboot_jsp_shiro.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月23日 9:47 星期六**/
@Controller
@RequestMapping("order")
public class orderController {//方式三:注解//@RequiresRoles("admin")    //用来判断角色(单一)//@RequiresRoles(value = {"admin","user"})    //用来判断角色表示同时具有@RequiresPermissions("user:update:01")      //权限字符串@RequestMapping("save")public String save() {System.out.println("进入方法");//获取主体对象Subject subject = SecurityUtils.getSubject();//方式一:代码方式if (subject.hasRole("admin")) {System.out.println("保存订单");} else {System.out.println("无权访问");}//方式二:基于权限字符串...return "redirect:/index.jsp";}}

角色信息数据库获取

shiro数据库
/*Navicat Premium Data TransferSource Server         : MySQLSource Server Type    : MySQLSource Server Version : 80013Source Host           : localhost:3306Source Schema         : shiroTarget Server Type    : MySQLTarget Server Version : 80013File Encoding         : 65001Date: 23/10/2021 10:53:50
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_pers
-- ----------------------------
DROP TABLE IF EXISTS `t_pers`;
CREATE TABLE `t_pers`  (`id` int(6) NOT NULL AUTO_INCREMENT,`name` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_pers
-- ------------------------------ ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role`  (`id` int(6) NOT NULL AUTO_INCREMENT,`name` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_role
-- ------------------------------ ----------------------------
-- Table structure for t_role_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_role_perms`;
CREATE TABLE `t_role_perms`  (`id` int(6) NOT NULL AUTO_INCREMENT,`roleid` int(6) NULL DEFAULT NULL,`permsid` int(6) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_role_perms
-- ------------------------------ ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`password` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, '13185020807', '90d43ef551bf0d455024b24f1f5760a1', '90^MZwku');
INSERT INTO `t_user` VALUES (2, 'xiaochen', 'aed28391070e3c36918f2d4d08f38089', '!Tr5*JpZ');-- ----------------------------
-- Table structure for t_user_roles
-- ----------------------------
DROP TABLE IF EXISTS `t_user_roles`;
CREATE TABLE `t_user_roles`  (`id` int(6) NOT NULL AUTO_INCREMENT,`userid` int(6) NULL DEFAULT NULL,`roleid` int(6) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_user_roles
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;
新建表

t_role

t_pers

t_role_perms

t_user_role

新建Role
package com.hz52.springboot_jsp_shiro.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月23日 11:10 星期六**/
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class Role {private String id;private String name;}
新建Perms
package com.hz52.springboot_jsp_shiro.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月23日 11:10 星期六**/
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class Perms {private String id;private String name;private String url;}
修改User
package com.hz52.springboot_jsp_shiro.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月20日 17:20 星期三**/
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {private String id;private String username;private String password;private String salt;/*** @Description: 定义角色集合* @Author: 52Hz* @Date: 2021/10/23* @Time: 11:14*/private List<Role> roles;}
修改UserDAO
package com.hz52.springboot_jsp_shiro.dao;import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月20日 17:27 星期三**/
@Mapper
public interface UserDAO {void save(User user);User findByUserName(String username);//根据用户查询所有角色User findRolesByUserName(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.hz52.springboot_jsp_shiro.dao.UserDAO"><insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_uservalues (#{id}, #{username}, #{password}, #{salt})</insert><select id="findByUserName" resultType="User" parameterType="String">select id, username, password, saltfrom t_userwhere username = #{username}</select><resultMap id="userMap" type="User"><id column="uid" property="id"/><result column="uname" property="username"/><!--角色信息--><collection property="roles" javaType="list" ofType="Role"><id column="rid" property="id"/><result column="rname" property="name"/></collection></resultMap><select id="findRolesByUserName" parameterType="String" resultMap="userMap">SELECT u.id       uid,u.username uname,r.id       rid,r.NAME     rnameFROM t_user uLEFT JOIN t_user_role ur ON u.id = ur.useridLEFT JOIN t_role r ON ur.roleid = r.idWHERE u.username = #{username}</select></mapper>
测试SQL

修改UserService
package com.hz52.springboot_jsp_shiro.service;import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:13 星期五**/
public interface UserService {//代表注册用户void register(User user);User findByUserName(String username);User findRolesByUserName(String username);}
修改UserServiceImpl
package com.hz52.springboot_jsp_shiro.service.impl;import com.hz52.springboot_jsp_shiro.Utils.SaltUtils;
import com.hz52.springboot_jsp_shiro.dao.UserDAO;
import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:14 星期五**/
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void register(User user) {//处理业务调用DAO//明文密码进行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);}@Overridepublic User findByUserName(String username) {return userDAO.findByUserName(username);}@Overridepublic User findRolesByUserName(String username) {return userDAO.findRolesByUserName(username);}
}
修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
import org.apache.commons.collections.ListUtils;
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.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.context.ApplicationContext;
import org.springframework.util.ObjectUtils;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();System.out.println("调用授权认证:" + primaryPrincipal);//根据主身份信息获取角色信息和权限信息UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findRolesByUserName(primaryPrincipal);//授权角色信息if (!CollectionUtils.isEmpty(user.getRoles())) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();user.getRoles().forEach(role -> {simpleAuthorizationInfo.addRole(role.getName());});return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
测试

权限信息数据库获取

修改Role
package com.hz52.springboot_jsp_shiro.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月23日 11:10 星期六**/
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class Role {private String id;private String name;/***@Description: 定义权限集合*@Author: 52Hz*@Date: 2021/10/23*@Time: 13:43*/private List<Perms> perms;}
修改t_pers

修改t_role_perms

修改UserService
package com.hz52.springboot_jsp_shiro.service;import com.hz52.springboot_jsp_shiro.entity.Perms;
import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:13 星期五**/
public interface UserService {//代表注册用户void register(User user);User findByUserName(String username);User findRolesByUserName(String username);//根据角色id查询权限集合List<Perms> findPermsByRid(String id);}
修改UserServiceImpl
package com.hz52.springboot_jsp_shiro.service.impl;import com.hz52.springboot_jsp_shiro.Utils.SaltUtils;
import com.hz52.springboot_jsp_shiro.dao.UserDAO;
import com.hz52.springboot_jsp_shiro.entity.Perms;
import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
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;/*** @Program: springboot_jsp_shiro* @Description:* @Author: 52Hz* @CreationTime: 2021年10月22日 10:14 星期五**/
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void register(User user) {//处理业务调用DAO//明文密码进行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);}@Overridepublic User findByUserName(String username) {return userDAO.findByUserName(username);}@Overridepublic User findRolesByUserName(String username) {return userDAO.findRolesByUserName(username);}@Overridepublic List<Perms> findPermsByRid(String id) {return userDAO.findPermsByRid(id);}}
修改CustomerRealm
package com.hz52.springboot_jsp_shiro.shiro.realms;import com.hz52.springboot_jsp_shiro.Utils.ApplicationContextUtils;
import com.hz52.springboot_jsp_shiro.entity.Perms;
import com.hz52.springboot_jsp_shiro.entity.Role;
import com.hz52.springboot_jsp_shiro.entity.User;
import com.hz52.springboot_jsp_shiro.service.UserService;
import org.apache.commons.collections.ListUtils;
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.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.context.ApplicationContext;
import org.springframework.util.ObjectUtils;import java.util.List;/*** @Program: springboot_jsp_shiro* @Description: 自定义realm* @Author: 52Hz* @CreationTime: 2021年10月20日 9:40 星期三**/
public class CustomerRealm extends AuthorizingRealm {//处理授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//获取身份信息String primaryPrincipal = (String) principals.getPrimaryPrincipal();System.out.println("调用授权认证:" + primaryPrincipal);//根据主身份信息获取角色信息和权限信息UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findRolesByUserName(primaryPrincipal);//授权角色信息if (!CollectionUtils.isEmpty(user.getRoles())) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();user.getRoles().forEach(role -> {//角色信息simpleAuthorizationInfo.addRole(role.getName());//权限信息List<Perms> perms = userService.findPermsByRid(role.getId());if (!CollectionUtils.isEmpty(perms)) {perms.forEach(perm -> {simpleAuthorizationInfo.addStringPermission(perm.getName());});}});return simpleAuthorizationInfo;}return null;}//处理认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String principal = (String) token.getPrincipal();//在工厂中 获取service对象UserService userService = (UserService) ApplicationContextUtils.getBean("userService");User user = userService.findByUserName(principal);if (!ObjectUtils.isEmpty(user)) {return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());}return null;}
}
修改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.hz52.springboot_jsp_shiro.dao.UserDAO"><insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_uservalues (#{id}, #{username}, #{password}, #{salt})</insert><select id="findByUserName" resultType="User" parameterType="String">select id, username, password, saltfrom t_userwhere username = #{username}</select><resultMap id="userMap" type="User"><id column="uid" property="id"/><result column="uname" property="username"/><!--角色信息--><collection property="roles" javaType="list" ofType="Role"><id column="rid" property="id"/><result column="rname" property="name"/></collection></resultMap><select id="findRolesByUserName" parameterType="String" resultMap="userMap">SELECT u.id       uid,u.username uname,r.id       rid,r.NAME     rnameFROM t_user uLEFT JOIN t_user_role ur ON u.id = ur.useridLEFT JOIN t_role r ON ur.roleid = r.idWHERE u.username = #{username}</select><select id="findPermsByRid" parameterType="String" resultType="Perms">SELECT p.id,p.NAME,p.url,r.NAMEFROM t_role rLEFT JOIN t_role_perms rp ON r.id = rp.roleidLEFT JOIN t_pers p ON rp.permsid = p.idWHERE r.id = #{id}</select></mapper>
修改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 http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h1>系统主页V1.0</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a><ul><shiro:hasAnyRoles name="user,admin"><li><a href="">用户管理</a></li><ul><shiro:hasPermission name="user:add:*"><li><a href="">添加</a></li></shiro:hasPermission><shiro:hasPermission name="user:delete:*"><li><a href="">删除</a></li></shiro:hasPermission><shiro:hasPermission name="user:update:*"><li><a href="">修改</a></li></shiro:hasPermission><shiro:hasPermission name="order:find:*"><li><a href="">查询</a></li></shiro:hasPermission></ul></shiro:hasAnyRoles><shiro:hasRole name="admin"><li><a href="">商品管理</a></li><li><a href="">订单管理</a></li><li><a href="">物流管理</a></li></shiro:hasRole></ul></body>
</html>
测试
xiaochen

zhangsan

六、Spring Boot整合Shiro相关推荐

  1. Spring Boot 整合 shiro 之盐值加密认证详解(六)

    Spring Boot 整合 shiro 之盐值加密认证详解 概述 不加盐认证 加入密码认证核心代码 修改 CustomRealm 新增获取密文的方法 修改 doGetAuthenticationIn ...

  2. Spring Boot整合Shiro + Springboot +vue

    目录 02 Spring Boot整合Shiro p1.shiro概述 1 什么是Shiro 2 Shiro核心组件 p2.Shiro实现登录认证 AccountRealm.java QueryWra ...

  3. Spring Boot 整合 Shiro(三)Kaptcha验证码 附源码

    前言 本文是根据上篇<Spring Boot 整合Shiro(二)加密登录与密码加盐处理>进行修改,如有不明白的转上篇文章了解. 1.导入依赖 <!-- https://mvnrep ...

  4. Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)

    在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...

  5. spring boot整合shiro继承redis_Springboot+Shiro+redis整合

    1.Shiro是Apache下的一个开源项目,我们称之为Apache Shiro.它是一个很易用与Java项目的的安全框架,提供了认证.授权.加密.会话管理,与spring Security 一样都是 ...

  6. spring boot整合shiro+jjwt

    前言 本篇文章将教大家在 shiro + springBoot 的基础上整合 JJWT (JSON Web Token) JWT JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允 ...

  7. spring boot整合Shiro实现单点登录

    默认情况下,Shiro已经为我们实现了和Cas的集成,我们加入集成的一些配置就ok了 1.加入shiro-cas包 <!-- shiro整合cas单点 --><dependency& ...

  8. Spring Boot 整合 Shiro

    虽然,直接用Spring Security和SpringBoot 进行"全家桶式"的合作是最好不过的,但现实总是欺负我们这些没办法决定架构类型的娃子. Apache Shiro 也 ...

  9. spring boot整合shiro继承redis_spring-boot-plus集成Shiro+JWT权限管理

    SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...

最新文章

  1. C# WinForm获取当前路径汇总
  2. 组队开发第二周第一次会议
  3. gis怎么通过水库划分子流域_到底是谁在革GIS的命?
  4. Python1:if / while / for...in / break /continue
  5. 继承_月隐学python第16课
  6. 实用程序类与函数式编程无关
  7. java计算器问题反馈,Java开发网 - 求教计算器问题(急~~~)
  8. [NOIP2015]金币
  9. 如何在 Ubuntu Linux 中打开终端(小白教程)
  10. 12 行列式01---定义、计算 与性质、排列、逆序数、n 阶行列式、上三角形行列、矩阵的初等行变换与行列式性质
  11. mysql把A表的数据插入到B表
  12. LoadRunner11 压力测试
  13. sap销售发货的流程_基于SAP系统批量创建销售订单及交货单过账的方法与流程
  14. Hexo博客新建文章以及Next主题多层级分类
  15. 【免费软件测试视频-0022】——Winrunner系列之---GUI快速脚本向导
  16. SAP各模块常用数据库表大全--->常用表
  17. 基于Matlab的自适应低通滤波器设计,基于MATLAB的自适应滤波器的设计
  18. codeforces 1153D Serval and Rooted Tree
  19. mysql5.7 离线安装_Linux离线安装MySQL5.7
  20. 自己写一个微型数据库_“最国际化的微型机构:”两名伦敦训练营的毕业生如何建造了一个远程…...

热门文章

  1. C - 喵帕斯之天才算数少女
  2. 职场未来十大趋势,比现实更魔幻!
  3. VR数字沙盘高度还原未来房屋实
  4. 沙盘正在注销进程start_沙盘报错:初始化Start.exe进程失败
  5. G1调优常用参数及其作用
  6. 【转】全屋WiFi覆盖无死角,Mesh组网是最佳选择!领势MR9000X组网实测
  7. 关于手游app的开发
  8. python自动买股票_用python可以做哪些有趣的事--我:选股票
  9. miix2 8 android,联想Miix28平板长测 8寸平板诠释Win8.1
  10. 浅谈元认知理论与学会学习