springboot+shiro,springboot集成shiro框架
00-1010 1.Spring Boot整合四郎创意2。环境构建2.1创建项目2.2引入依赖项2.3创建前端页面2.4配置视图信息2.5解决想法冲突2.6测试构建的环境3。集成Shiro3.1引入依赖项3.2定制Realm3.3 Shiro配置3.4开始测试4。经常看到过滤器5。认证和退出5.1。在index.jsp 5.2中添加一个标签。写控制器5.3 .修改自定义Realm5.4 .修改ShiroConfig配置5.5测试6。MDS alt 6.1的认证实现。创建数据库6.2。引入依赖6.3。配置数据源并集成mybatis6.4 .创建实体类entit。Y6.5创建DAO接口6.6编写映射器配置文件6.7创建服务接口6.8编写生成随机salt工具类6.9编写服务实现类6.10编写控制器6.11修改自定义Realm6.12编写获取对象工具类6.13修改Config6.14添加注册页面6.15测试7。授权实现7.1模拟数据实现授权7.1.1模拟数据7.1.2页面资源授权7.1.3代码模式授权7.1.4方法调用授权7.2数据库实现角色授权7.2.1授权数据持久化7.2.2创建数据库表7.2.3创建实体类7.2.4创建Dao接口7.2.5写映射器服务接口7.2.7写服务实现方法7.2.8修改自定义Realm7.3数据库实现权限7.3.1创建Dao接口7.3.2写shiro使用cache 8.1 Cache8.1.1缓存功能8.1.2使用shiro中默认的EhCache实现缓存8.1.3测试8.2 Redis8.2.1 shiro使用Redis作为缓存实现8。测试9。shrio实现验证功能9.1验证码工具类9.2开发页面加入验证码9.3开发控制器9.4发布验证码9.5修改认证流程9.6开始测试10。jsp 11中使用了shiro标签。shiro集成springboot的百里叶权限控制11.1引入依赖11.2页面引入命名空间11.3常用权限控制标签使用11.4 Join Shiro方言配置
目录
1.SpringBoot整合Shiro思路
2. 环境搭建
2.1 创建项目
pom.xml
依赖项依赖项groupIdorg.springframework.boot/groupId artifact id spring-boot-starter-web/artifact id/dependency artifact id spring-boot-dev tools/artifact id scope runtime/scope options true/可选groupIdorg.projectlombok/groupId artifact id lombok/artifact id artifact id spring-boot-starter-test/artifact id scope test/scope!-介绍Jsp dependency-groupIdorg.apache.tomcat.embed/groupId artifactid Tomcat-embed-jasper/artifactid!-jstl-groupId jstl/groupId artifactId jstl/artifactId版本1.2/version/dependencies build gt
; <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins></build>
2.3 创建前端页面
在webapp文件夹中创建index.jsp和login.jspindex.jsp
<%@page contentType="text/html;UTF-8" pageEncoding="UTF-8" isErrorPage="false" %><!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body><%--受限资源--%><h1>系统主页</h1><ul> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >用户管理</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >商品管理</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >订单管理</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >物流管理</a></li></ul></body></html>
login.jsp
<%@page contentType="text/html;UTF-8" pageEncoding="UTF-8" isErrorPage="false" %><!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>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></html>
2.4 配置视图信息
application.properties
server.port=8080server.servlet.context-path=/shirospring.application.name=shirospring.mvc.view.prefix=/spring.mvc.view.suffix=.jsp
2.5 解决IDEA冲突问题
JSP 与IDEA 与SpringBoot存在一定的不兼容,修改此配置即可解决
2.6 测试搭建的环境
3. 整合Shiro
3.1 引入依赖
pom.xml
<!--引入shrio--><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.5.3</version></dependency>
3.2 自定义Realm
在shiro文件夹下创建realm文件夹
package com.test.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;/** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { return null; }}
3.3 Shiro配置
在config文件夹中创建ShiroConfig.java
@Configurationpublic class ShiroConfig { //ShiroFilter过滤所有请求 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //给ShiroFilter配置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //配置系统受限资源 //配置系统公共资源 Map<String, String> map = new HashMap<String, String>(); map.put("/index.jsp","authc");//表示这个资源需要认证和授权 // 设置认证界面路径 shiroFilterFactoryBean.setLoginUrl("/login.jsp"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } //创建安全管理器 @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } //创建自定义Realm @Bean public Realm getRealm() { CustomerRealm realm = new CustomerRealm(); return realm; }}
3.4 启动测试
输入http://localhost:8080/shiro/index.jsp,发现需要跳转到login.jsp
4. 常见过滤器
注意: shiro提供和多个默认的过滤器,我们可以用这些过滤器来配置控制指定url的权限:
5. 认证和退出
5.1 在index.jsp添加a标签
index.jsp
<a href="${pageContext.request.contextPath}/user/logout" rel="external nofollow" rel="external nofollow" >退出登录</a>
5.2 编写controller
UserController.java
@Controller@RequestMapping("/user")public class UserController { @RequestMapping("logout") public String logout() { Subject subject = SecurityUtils.getSubject(); subject.logout(); return "redirect:/login.jsp"; } @RequestMapping("/login") public String login(String username, String password) { //获取主题对象 Subject subject = SecurityUtils.getSubject(); try { subject.login(new UsernamePasswordToken(username,password)); System.out.println("登录成功!!!"); return "redirect:/index.jsp"; } catch (UnknownAccountException e) { e.printStackTrace(); System.out.println("用户错误!!!"); } catch (IncorrectCredentialsException e) { System.out.println("密码错误!!!"); } return "redirect:/login.jsp"; }}
5.3 修改自定义Realm
CustomerRealm.java
/** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String principal = (String) authenticationToken.getPrincipal(); if ("zhangsan".equals(principal)) { return new SimpleAuthenticationInfo(principal,"123456",this.getName()); } return null; }}
5.4 修改ShiroConfig配置
ShiroConfig.java公共资源一定是在受限资源上面,不然会造成死循环。
@Configurationpublic class ShiroConfig { //ShiroFilter过滤所有请求 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //给ShiroFilter配置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //配置系统受限资源 //配置系统公共资源 Map<String, String> map = new HashMap<String, String>(); map.put("/user/login","anon");//表示这个为公共资源 一定是在受限资源上面 map.put("/**","authc");//表示这个受限资源需要认证和授权 // 设置认证界面路径 shiroFilterFactoryBean.setLoginUrl("/login.jsp"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } //创建安全管理器 @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } //创建自定义Realm @Bean public Realm getRealm() { CustomerRealm realm = new CustomerRealm(); return realm; }}
5.5 测试
登录正常,登出正常,未登录和登出后不能访问index.jsp
6. MDSalt的认证实现
6.1 创建数据库
SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for t_user-- ----------------------------DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` ( `id` INT(6) NOT NULL AUTO_INCREMENT, `username` VARCHAR(40) DEFAULT NULL, `password` VARCHAR(40) DEFAULT NULL, `salt` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;SET FOREIGN_KEY_CHECKS = 1;
6.2 引入依赖
<!--引入mybatis--><dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version></dependency><!--mysql--><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId></dependency><!--druid--><dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.6</version></dependency>
6.3 配置数据源和整合mybatis
application.properties
#配置数据源spring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/springboot_shrio?characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=123456mybatis.type-aliases-package=com.test.entitymybatis.mapper-locations=classpath:com/test/mapper/*.xml
6.4 创建实体类entity
User.java
@Data@Accessors(chain = true)@NoArgsConstructor@AllArgsConstructorpublic class User { private String id; private String username; private String password; private String salt;}
6.5 创建DAO接口
UserDao.java
@Mapper@Repositorypublic interface UserDao { void save(User user); User findByUsername(String username);}
6.6 编写Mapper配置文件
UserDao.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.test.dao.UserDao"> <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id"> insert into t_user values(#{id},#{username},#{password},#{salt}) </insert> <select id="findByUsername" parameterType="String" resultType="User"> select id,username,password,salt from t_user where username = #{username} </select></mapper>
6.7 创建Service接口
UserService.java
public interface UserService { //注册用户方法 void register(User user); //根据用户名查找用户 User findByUsername(String username);}
6.8 编写生成随机盐工具类
SaltUtil.java
public class SaltUtil { public static String getSalt(int n) { char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()".toCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < n; i++) { char c = chars[new Random().nextInt(chars.length)]; sb.append(c); } return sb.toString(); } public static void main(String[] args) { System.out.println(getSalt(4)); }}
6.9 编写Service实现类
UserServiceImpl.java
@Service("userService")@Transactionalpublic class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public void register(User user) { //1.获取随机盐 String salt = SaltUtil.getSalt(8); //2.将随机盐保存到数据 user.setSalt(salt); //3.明文密码进行md5 + salt + hash散列 Md5Hash MD5 = new Md5Hash(user.getPassword(),salt,1024); user.setPassword(MD5.toHex()); userDao.save(user); } @Override public User findByUsername(String username) { return userDao.findByUsername(username); }}
6.10 编写Controller
UserController.java
@Controller@RequestMapping("/user")public class UserController { @Autowired private UserService userService; @RequestMapping("/register") public String register(User user) { try { userService.register(user); return "redirect:/login.jsp"; } catch (Exception e) { e.printStackTrace(); return "redirect:/register.jsp"; } } @RequestMapping("logout") public String logout() { Subject subject = SecurityUtils.getSubject(); subject.logout(); return "redirect:/login.jsp"; } @RequestMapping("/login") public String login(String username, String password) { //获取主题对象 Subject subject = SecurityUtils.getSubject(); try { subject.login(new UsernamePasswordToken(username,password)); System.out.println("登录成功!!!"); return "redirect:/index.jsp"; } catch (UnknownAccountException e) { e.printStackTrace(); System.out.println("用户错误!!!"); } catch (IncorrectCredentialsException e) { System.out.println("密码错误!!!"); } return "redirect:/login.jsp"; }}
6.11 修改自定义Realm
CustomerRealm.java
/** * 自定义Realm */public class CustomerRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String principal = (String) authenticationToken.getPrincipal(); //获取UserService对象 UserService userService = (UserService) ApplicationContextUtil.getBean("userService"); //System.out.println(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; }}
6.12 编写获取对象工具类
ApplicationContextUtil.java
@Componentpublic class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } //根据bean名字获取工厂中指定bean 对象 public static Object getBean(String beanName) { return context.getBean(beanName); }}
6.13 修改Config
ShiroConfig.java
@Configurationpublic class ShiroConfig { //ShiroFilter过滤所有请求 @Bean public
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。