狂神说Java之Springboot整合Shiro
Springboot整合Shiro
文章是观看狂神说Java的Springboot整合Shiro的视频时写的随笔,大家可以参考下编写代码的过程,里面也有我写的一点注意事项。
完整代码我已经放在gitee上了,需要的可以自取。也可以参考我后面参考引用的博主的博客,里面也有完整的代码。
加油!打工人!
一、实验过程
目录结构
service层再建个impl包会更加层次分明
1、实验准备
1.1 导入依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.2</version>
</dependency>
1.2 前端页面
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h>首页</h><!--/*@thymesVar id="msg" type=""*/--><div th:text="${msg}"></div><a th:href="@{/user/add}">add</a><a th:href="@{/user/update}">update</a></body>
</html>
login
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>登录</h1><hr><form th:action="@{/login}">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" name="提交"></form>
</body>
</html>
add
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h>add</h>
</body>
</html>
update
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h> update </h>
</body>
</html>
1.3 数据库准备
create table user
(id int(20) auto_increment primary key,name varchar(30) null,pwd varchar(30) null,perms varchar(50) null
)charset = utf8;
2、测试01
设置访问权限,如果没权限则进入登陆界面
2.1 编写Shiro配置类
思路:ShiroFilterFactoryBean会拦截前端请求交给DefaultWebSecurityManager,再交给userRealm进行认证和授权处理
主要编写userRealm、DefaultWebSecurityManager、ShiroFilterFactoryBean三个bean对象
注意:我们可以从下往上写,逐步添加
@Configuration
public class ShiroConfig {//ShiroFilterFactoryBean (第三步:连接到前端)@Beanpublic ShiroFilterFactoryBean getShiroFilterBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebSecurityManager);return bean;}//DefaultWebSecurityManager (第二步:管理realm对象)@Bean(name="securityManager")public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();//关联UserRealmsecurityManager.setRealm(userRealm);return securityManager;}//创建realm对象,需要自定义类 (第一步:创建realm对象)@Bean(name="userRealm") //@Bean注解后便被spring托管,不加name属性,默认name值为方法名,这里就加一下吧public UserRealm userRealm(){return new UserRealm();}}
在ShiroFilterFactoryBean方法内添加过滤器,设置访问权限,如果没权限则进入登陆界面
//添加shiro的内置过滤器
/*
anon: 无需认证即可访问
authc: 必须认证才能用
user: 必须拥有 “记住我” 功能才能用
perms: 拥有对某个资源的权限才能用
role: 拥有某个角色权限才能访问
*/Map<String,String> filterMap = new LinkedHashMap<>();
//拦截
filterMap.put("/user/add","anon");
filterMap.put("/user/update","authc");
//也可使用通配符*
//filterMap.put("/user/*","authc");bean.setFilterChainDefinitionMap(filterMap);
//若访问时用户未认证,则跳转至登录页面
bean.setLoginUrl("/toLogin");
2.2 编写UserRealm类
只要进行登陆操作(subject.login)就会执行doGetAuthenticationInfo方法
//自定义UserRealm extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行了授权");return null;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("执行了认证");return null;}
}
2.3 编写HellloController进行测试结果
@Controller
public class HellloController {@RequestMapping({"/", "/index"})public String toIndex(Model model){model.addAttribute("msg", "hello");return "index";}@RequestMapping("/user/add")public String add(){return "/user/add";}@RequestMapping("/user/update")public String update(){return "/user/update";}@RequestMapping("/toLogin")public String toLogin(){return "login";}
}
3、登陆认证
整体流程:当我们在登陆页面输入账号密码,会执行HelloController的login登陆操作,在使用subject.login(token)时会执行shiro里的UserRealm里的认证方法doGetAuthenticationInfo。
在HelloController中添加登陆认证方法,都是根据入门案例来写的
@RequestMapping("/login")public String login(String username,String password,Model model){//获取当前用户Subject subject = SecurityUtils.getSubject();//封装用户的登录数据UsernamePasswordToken token = new UsernamePasswordToken(username, password);try{subject.login(token); //执行登录的方法,如果没有异常就说明ok了return "index";}catch (UnknownAccountException e){ //用户名不存在model.addAttribute("msg","用户名不存在!");return "login";}catch (IncorrectCredentialsException e){model.addAttribute("msg","密码错误!");return "login";}}
当我们执行 subject.login登陆操作时,Shiro会执行UserRealm里的认证方法doGetAuthenticationInfo
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("执行了认证");//用户名、密码 模拟从数据库中获取String name = "root";String password = "1111";UsernamePasswordToken userToken = (UsernamePasswordToken) token;if (!userToken.getUsername().equals(name)){return null; //抛出异常 UnknownAccountException}//密码认证,shiro做~return new SimpleAuthenticationInfo("",password,"");}
4、整合Mybatis
目标:使的用户登陆认证数据从数据库中取出
4.1 导入依赖
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.18</version>
</dependency>
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version>
</dependency>
4.2 配置application.yml
这里配置mybatis扫描的包和别名
spring:datasource:username : rootpassword: qrj15521026074url : jdbc:mysql://localhost:3306/mybatis01?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource # 自定义数据源#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500mybatis:type-aliases-package: com.qiu.pojomapper-locations: classpath:mapper/*.xml
4.3配置UserMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.qiu.mapper.UserMapper"><select id="queryUserByName" parameterType="String" resultType="com.qiu.pojo.User">select * from user where name = #{name};</select></mapper>
4.4 编写主要类和接口
编写User类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;private String pwd;private String perms;
}
编写UserMapper接口
@Repository
@Mapper
public interface UserMapper {public User queryUserByName(String name);
}
编写UserService接口
public interface UserService {public User queryUserByName(String name);
}
编写UserServiceImpl实现类
@Service
public class UserServiceImpl implements UserService{@AutowiredUserMapper userMapper;@Overridepublic User queryUserByName(String name) {return userMapper.queryUserByName(name);}}
4.5 重新编写UserRealm类
让用户数据连接数据库
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("执行了认证");/*//用户名、密码 模拟从数据库中获取String name = "root";String password = "1111";if (!userToken.getUsername().equals(name)){return null; //抛出异常 UnknownAccountException}//密码认证,shiro做~return new SimpleAuthenticationInfo("",password,"");*/UsernamePasswordToken userToken = (UsernamePasswordToken) token;//连接数据库User user = userService.queryUserByName(userToken.getUsername());if (user == null){return null; //抛出异常 UnknownAccountException}//密码认证,shiro做~return new SimpleAuthenticationInfo("",user.getPwd(),"");}
5、请求授权
目标:通过从数据库中获取用户权限资源,访问对应权限的方法
5.1 重写ShiroConfig
user类增加一个perms权限访问
在ShiroConfig中设置拦截登陆
@Beanpublic ShiroFilterFactoryBean getShiroFilterBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebSecurityManager);//添加shiro的内置过滤器/*anon: 无需认证即可访问authc: 必须认证才能用user: 必须拥有 “记住我” 功能才能用perms: 拥有对某个资源的权限才能用role: 拥有某个角色权限才能访问*/Map<String,String> filterMap = new LinkedHashMap<>();//登陆认证拦截:未登录会跳转登陆页面filterMap.put("/user/add","anon");filterMap.put("/user/update","authc");//也可使用通配符*//filterMap.put("/user/*","authc");//登陆后授权,正常情况下没有授权会跳转到未授权页面filterMap.put("/user/add","perms[user:add]");filterMap.put("/user/update","perms[user:update]");bean.setFilterChainDefinitionMap(filterMap);//若访问时用户未认证,则跳转至登录页面bean.setLoginUrl("/toLogin");//若访问时用户未被授权,则跳转至未授权页面bean.setUnauthorizedUrl("/noauth");return bean;}
5.2 重写UserRealm
添加用户的权限,从认证中获取用户信息,取出权限perms
//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行了授权");SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//授权操作//info.addStringPermission("user:add");//拿到当前登录的对象Subject subject = SecurityUtils.getSubject();User currentUser = (User) subject.getPrincipal(); //拿到user对象System.out.println(currentUser.getPerms());info.addStringPermission(currentUser.getPerms());return info;}
这里要在认证doGetAuthenticationInfo方法里return时传入user资源,使之能在授权方法中使用获取权限资源
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("执行了认证");//...................//这里在登陆后传入user资源return new SimpleAuthenticationInfo(user,user.getPwd(),"");}
5.3 在HellloController添加未授权操作
@RequestMapping("/noauth")@ResponseBodypublic String unauthorized(){return "未授权无法访问此页面";}
6、整合thymeleaf
目标:实现特点用户访问特定页面,权限不同,访问到的功能不同
6.1 导入依赖
<!--导入thymeleaf依赖--><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.11.RELEASE</version></dependency><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-java8time</artifactId><version>3.0.4.RELEASE</version></dependency><!--shiro-thymeleaf整合-->
<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version>
</dependency>
6.2 在ShiroConfig添加整合thymeleaf
//整合ShiroDialect:用来整合shiro thymeleaf@Beanpublic ShiroDialect getShiroDialect(){return new ShiroDialect();}
6.3 使用thymeleaf重写index登陆页面
导入shiro和thymeleaf的约束
通过shiro:hasPermission指定权限
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro" >
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>首页</h1><div th:if="${session.loginUser==null}"><a th:href="@{/toLogin}">登录</a></div><p th:text="${msg}"></p><hr><div shiro:hasPermission="user:add"><a th:href="@{/user/add}">add</a></div><div shiro:hasPermission="user:update"><a th:href="@{/user/update}">update</a></div><a th:href="@{/logout}">注销</a>
</body>
</html>
7、结果
数据库权限
root账号登陆界面
狂神账号登陆界面
二、实验问题
1、插件报错
打包遇到错误Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test
解决办法:修改pom.xml文件
<plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.19.1</version></plugin>
</plugins>
2、IDEA2020.1启动SpringBoot项目出现java程序包:xxx不存在
setting->bulid,execution,Deployment->bulid tools->maven->runner
勾选上Delegate ide bulid/run actions to Maven
参考:IDEA2020.1启动SpringBoot项目出现java程序包:xxx不存在
参考
【狂神说Java】SpringBoot整合Shiro框架
SpringBoot整合Shiro
)
狂神说Java之Springboot整合Shiro相关推荐
- 狂神说Java 之SpringBoot整合Shiro框架笔记!
参考:https://www.bilibili.com/video/BV1NE411i7S8 1,通过·subject获取用户.还有session获取! 2,判断登录用户. 未注册 密码不对 账号被锁 ...
- SpringBoot整合Shiro实现登录认证和授权CHCache
文章目录 一. springboot实现普通登录 1 添加依赖 2 编写配置文件 3 新建实体类和mapper 4 编写业务层代码 5 编写控制器 6 编写启动类 7 编写登录页面和主页面 二. sp ...
- 补习系列(6)- springboot 整合 shiro 一指禅
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- SpringBoot整合Shiro实现权限控制,验证码
本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...
- SpringBoot 整合Shiro 一指禅
目标 了解ApacheShiro是什么,能做什么: 通过QuickStart 代码领会 Shiro的关键概念: 能基于SpringBoot 整合Shiro 实现URL安全访问: 掌握基于注解的方法,以 ...
- SpringBoot整合Shiro搭建登录注册认证授权权限项目模板
主要内容: 1 SpringBoot整合Shiro安全框架; 2 Shiro主要学习内容总结;(执行流程.主要对象接口.注意事项等) 3 Redis实现对权限信息缓存; ! 温馨提示: 想要快速搭Sh ...
- SpringBoot整合Shiro学习(上)
SpringBoot整合Shiro(上) 基于[编程不良人]2020最新版Shiro教程,整合SpringBoot项目实战教程 哔哩哔哩链接:https://www.bilibili.com/vide ...
- springboot整合shiro
springboot整合shiro 导入依赖 <!-- shiro鉴权框架--> <dependency><groupId>org.apache.shiro< ...
- 关于SpringBoot整合Shiro并入redis缓存
关于SpringBoot整合Shiro并入redis缓存 最近做一个小项目加入shiro权限框架, Shiro是Apache下的一个开源项目,提供了认证.授权.加密.会话管理,与spring Secu ...
- Springboot整合Shiro前后端分离跨域问题
Springboot整合Shiro前后端分离跨域问题 前言:SpringBoot整合shiro进行前后端分离开发时(前端是Vue),项目做了跨域配置,但还是前端请求会出现cros err–显示的跨域问 ...
最新文章
- 解决chrome 很卡的问题
- 机器学习之神经网络模型-下(Neural Networks: Representation)
- java中使用akka手记三 cluster详例
- phpcms9-6-0 一键getshell工具
- asp.net core 3.0 gRPC框架小试
- wordpress安装到虚拟服务器,将WordPress安装在虚拟主机二级目录的方法
- linux 内存使用很大,在32位和64位Linux上,为什么同一进程的pmap的内存使用量会有很大差异?...
- docker用gpu的参数_初探Docker调用GPU
- 公司来的新同事能力没我强,但是工资比我高,我应该提出加薪还是选择辞职?
- 《Android Jetpack》— Android 书籍
- ZOJ 1203[Swordfish]
- 企业微信:上传图片获取永久url --Java
- 剖析Apple Pay 它与支付宝究竟暧昧什么?
- cocos creator3.x h5项目启动背景修改,仅限单色
- 如何TIA博途中更新HSP硬件目录?
- 亚马逊商品图片使用技巧和规范你都了解吗?
- 我的开源项目,趣享GIF源代码已正式公开
- 免费的几个CDN加速
- vsftpd2.3.4笑脸漏洞
- 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛B合约数
热门文章
- asp.net914-自驾游网站的设计与实现
- 访问项目,页面打开太慢解决方式
- 腾格尔刚刚参加线上演唱会,又传《巴林塔娜》合作主题曲身价倍增
- 美国企业家宣言(转)
- 统计套利之平稳性检验
- autoit mysql update_RobotFramework+selenium+requests+autoit+mysql+appium 环境搭建
- 如何把苍白的一年写成耀眼的年终报告?写完当场加薪的那种
- 手机射频中的常见术语
- 如何使用Keras fit和fit_generator(动手教程)
- 信息安全技术——(十五)物联网关键技术