springboot+shiro,springboot集成shiro框架

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: