六、Spring Boot整合Shiro
六、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相关推荐
- Spring Boot 整合 shiro 之盐值加密认证详解(六)
Spring Boot 整合 shiro 之盐值加密认证详解 概述 不加盐认证 加入密码认证核心代码 修改 CustomRealm 新增获取密文的方法 修改 doGetAuthenticationIn ...
- Spring Boot整合Shiro + Springboot +vue
目录 02 Spring Boot整合Shiro p1.shiro概述 1 什么是Shiro 2 Shiro核心组件 p2.Shiro实现登录认证 AccountRealm.java QueryWra ...
- Spring Boot 整合 Shiro(三)Kaptcha验证码 附源码
前言 本文是根据上篇<Spring Boot 整合Shiro(二)加密登录与密码加盐处理>进行修改,如有不明白的转上篇文章了解. 1.导入依赖 <!-- https://mvnrep ...
- Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)
在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...
- spring boot整合shiro继承redis_Springboot+Shiro+redis整合
1.Shiro是Apache下的一个开源项目,我们称之为Apache Shiro.它是一个很易用与Java项目的的安全框架,提供了认证.授权.加密.会话管理,与spring Security 一样都是 ...
- spring boot整合shiro+jjwt
前言 本篇文章将教大家在 shiro + springBoot 的基础上整合 JJWT (JSON Web Token) JWT JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允 ...
- spring boot整合Shiro实现单点登录
默认情况下,Shiro已经为我们实现了和Cas的集成,我们加入集成的一些配置就ok了 1.加入shiro-cas包 <!-- shiro整合cas单点 --><dependency& ...
- Spring Boot 整合 Shiro
虽然,直接用Spring Security和SpringBoot 进行"全家桶式"的合作是最好不过的,但现实总是欺负我们这些没办法决定架构类型的娃子. Apache Shiro 也 ...
- spring boot整合shiro继承redis_spring-boot-plus集成Shiro+JWT权限管理
SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...
最新文章
- C# WinForm获取当前路径汇总
- 组队开发第二周第一次会议
- gis怎么通过水库划分子流域_到底是谁在革GIS的命?
- Python1:if / while / for...in / break /continue
- 继承_月隐学python第16课
- 实用程序类与函数式编程无关
- java计算器问题反馈,Java开发网 - 求教计算器问题(急~~~)
- [NOIP2015]金币
- 如何在 Ubuntu Linux 中打开终端(小白教程)
- 12 行列式01---定义、计算 与性质、排列、逆序数、n 阶行列式、上三角形行列、矩阵的初等行变换与行列式性质
- mysql把A表的数据插入到B表
- LoadRunner11 压力测试
- sap销售发货的流程_基于SAP系统批量创建销售订单及交货单过账的方法与流程
- Hexo博客新建文章以及Next主题多层级分类
- 【免费软件测试视频-0022】——Winrunner系列之---GUI快速脚本向导
- SAP各模块常用数据库表大全--->常用表
- 基于Matlab的自适应低通滤波器设计,基于MATLAB的自适应滤波器的设计
- codeforces 1153D Serval and Rooted Tree
- mysql5.7 离线安装_Linux离线安装MySQL5.7
- 自己写一个微型数据库_“最国际化的微型机构:”两名伦敦训练营的毕业生如何建造了一个远程…...