Springboot整合shiro框架
程序员文章站
2022-05-28 21:17:40
shiro概述 1. Apache Shiro是Java的一个安全框架 2. Shiro是一个强大的简单易用的Java安全框架,主要用来更便捷的认证、授权、加密、会话管理、与Web集成、缓存等 3. Shiro使用起来小而简单 3. spring中有spring security ,是一个权限框架, ......
shiro概述
- apache shiro是java的一个安全框架
- shiro是一个强大的简单易用的java安全框架,主要用来更便捷的认证、授权、加密、会话管理、与web集成、缓存等
- shiro使用起来小而简单
- spring中有spring security ,是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
- shiro不依赖于spring,shiro不仅可以实现web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,
- shiro属于轻量框架,越来越多企业项目开始使用shiro.
shiro核心概念
- authentication:身份认证/登录,验证用户是不是拥有相应的身份;
- authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
- session manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;
- cryptography:加密,保护数据的安全性
- web support:web支持,可以非常容易的集成到web环境;
- caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
- concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
- testing:提供测试支持;
- run as:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- remember me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
主要概念
1. subject 当前的操作用户
- 可以是人 爬虫 当前跟软件交互的东西
- 在shiro当中我们可以统称"用户" 在代码的任何地方,你都能轻易的获得shiro subject。
- 一旦获得subject,你就可以立即获得你希望用shiro为当前用户做的90%的事情 ,登录、退、访问会话、执行授权检查等
2. securitymanager
- securitymanager则管理所有用户的安全操作
- 引用了多个内部嵌套安全组件,是shiro框架的核心
- 你可以把它看成dispatcherservlet前端控制器。
- 用于调度各种shiro框架的服务
3. realms
- realms则是用户的信息认证器和用户的权限认证器
- 执行认证(登录)和授权(访问控制)时,shiro会从应用配置的realm中查找很多内容
- realm 可以理解为读取用户信息、角色及权限的 dao
- securitymanager要验证用户身份与权限,那么它需要从realm获取相应的信息进行比较以确定用户身份是否合法;
- 可以把realm看成datasource,即安全数据源。
4. shiro架构
- subject:主体 主体可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
- authenticator: 认证器 主体进行认证最终通过authenticator进行的。
- authorizer: 授权器 主体进行授权最终通过authenticator进行的。
- sessionmanager:会话管理 web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。
- sessiondao: 通过sessiondao管理session数据,
- cachemanager: 缓存管理器 主要对session和授权数据进行缓存,比如将授权数据通过cachemanager进行缓存管理,和 ehcache整合对缓存数据进行管理。
- realm: 领域 相当于数据源,通过realm存取认证、授权相关数据。
- cryptography: 密码管理 提供了一套加密/解密的组件,方便开发。比如 提供常用的散列、加/解密等功能。
springboot整合shiro
-
新建一个springboot项目
-
导入springboot-web依赖
-
编写controller和前端登录页面
需要整合thymeleaf 加入thymeleaf的依赖
<!--thymeleaf依赖--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-thymeleaf</artifactid> </dependency> <dependency> <groupid>org.thymeleaf.extras</groupid> <artifactid>thymeleaf-extras-java8time</artifactid> </dependency>
4. 编写前端页面
在templates目录下编写 login.html,add.html,delete.html,index.html
导入thymeleaf的dtd
xmlns:th="http://www.thymeleaf.org"
login.html
<!doctype html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <title>登录</title> </head> <body> <form th:action="login"> <input type="text" name="username" value=""> <input type="password" name="password" value=""> <input type="submit" value="登录"> </form> </body> </html>
index.html
add.html
delete.html
5. 编写controller,跳转到登录页面的方法
@requestmapping({"/","tologin"}) public string tologin(){ return "login"; }
- 运行启动 浏览器输入localhost:8080
- 导入springboot整合shiro和mybatis连接数据库的依赖
<!--shiro-整合spring的包--> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-spring</artifactid> <version>1.4.2</version> </dependency> <!--shiro整合thymeleaf--> <dependency> <groupid>com.github.theborakompanioni</groupid> <artifactid>thymeleaf-extras-shiro</artifactid> <version>2.0.0</version> </dependency> <!--mybatis--> <dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>1.3.2</version> </dependency> <!--mysql--> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>5.1.38</version> </dependency>
- 创建数据库 进行下一步的认证授权
##配置数据驱动信息 (key固定) spring.datasource.driverclassname = com.mysql.jdbc.driver spring.datasource.url = jdbc:mysql:///spring_shiro spring.datasource.username = root spring.datasource.password =123456
在application.properties中添加数据库信息
- 编写mapper,service,pojo
pojo:
mapper:
service:
impl:
controller:测试是否能够查询到
- 编写shiroconfig配置类
- 编写realm类 继承authorizingrealm类 并实现方法
- 在shiroconfig中编写代码
@configuration public class shiroconfig { //3. shirofilterfactarybean @bean public shirofilterfactorybean getshirofilterfactorybean(@qualifier("getdefaultwebsecuritymanager") defaultwebsecuritymanager defaultwebsecuritymanager){ shirofilterfactorybean shirofilterfactorybean = new shirofilterfactorybean(); shirofilterfactorybean.setsecuritymanager(defaultwebsecuritymanager);//设置安全管理器 shirofilterfactorybean.setloginurl("/tologin");//没有认证后跳到的页面 /** * shiro的内置过滤器 anon:无需认证就可以访问 默认 authc:必须认证了才能访问 user:必须拥有记住我功能才能访问 perms:必须拥有对某个的权限才能访问 role:拥有某个角色权限才能访问 */ //添加shiro的内置过滤器 设置要拦截的url map<string,string> filterchaindefinitionmap=new linkedhashmap<>();//拦截 filterchaindefinitionmap.put("/add","authc");// /add请求必须认证才能访问 filterchaindefinitionmap.put("/del","authc");//del必须认证才能访问 // filterchaindefinitionmap.put("user/**","authc");//支持通配符 //授权 filterchaindefinitionmap.put("/add","perms[user:add]");//没有这个user:add权限的会被拦截下来 filterchaindefinitionmap.put("/del","perms[user:delete]");//没有这个user:delete权限的会被拦截下来 //未授权的跳转的url shirofilterfactorybean.setunauthorizedurl("/unauthorized"); //设置注销的url shirofilterfactorybean.setfilterchaindefinitionmap(filterchaindefinitionmap);//把设置好的过滤设置到shirofilterfactorybean return shirofilterfactorybean; } //2. defaultwebsecuritymanager @bean public defaultwebsecuritymanager getdefaultwebsecuritymanager(@qualifier("userrealm") userrealm userrealm){ defaultwebsecuritymanager securitymanager = new defaultwebsecuritymanager(); //关联realm对象 userrealm securitymanager.setrealm(userrealm); return securitymanager; } //1. 创建realm对象 自定义的·类 @bean public userrealm userrealm(){ return new userrealm(); } //整合shirodialect:用来整合shiro-thymeleaf @bean public shirodialect getshirodialect(){ return new shirodialect(); } }
- 在userrealm编写代码
public class userrealm extends authorizingrealm { @autowired infoservice service; //授权 @override protected authorizationinfo dogetauthorizationinfo(principalcollection principalcollection) { system.out.println("执行了授权 dogetauthorizationinfo"); simpleauthorizationinfo simpinfo = new simpleauthorizationinfo(); //获取当前用户的对象 subject subject=securityutils.getsubject(); info user = (info)subject.getprincipal();//获取用户信息 simpinfo.addstringpermission(user.getperm());//获取数据库权限 return simpinfo; } //认证 @override protected authenticationinfo dogetauthenticationinfo(authenticationtoken authenticationtoken) throws authenticationexception { system.out.println("执行了认证 dogetauthorizationinfo"); //获取当前的用户 subject subject = securityutils.getsubject(); usernamepasswordtoken usertoken=(usernamepasswordtoken)authenticationtoken;//获取登录的信息 //获取用户名 密码 数据库取 system.out.println(usertoken.getusername()); info query = service.querybyname(usertoken.getusername()); system.out.println(query); if(query==null){//没有这个用户 return null; } session session=subject.getsession();//获取用户的session session.setattribute("loginuser",query); if(!usertoken.getusername().equals(query.getusername())){//判断登录的用户名密码 匹配数据库是否正确 return null;//抛出异常 } //密码认证,shiro做 return new simpleauthenticationinfo(query,query.getpassword(),""); } }
14. 改写controller
@requestmapping("/login") public string login(string username,string password){ try { //获取当前的用户 subject subject = securityutils.getsubject(); //封装用户的登录数据 usernamepasswordtoken usernamepasswordtoken = new usernamepasswordtoken(username, password); subject.login(usernamepasswordtoken);//执行登录的方法 没有异常就成功了 return "index"; } catch (unknownaccountexception e) { /** * 异常信息 * unknownaccountexception :用户名不存在 * incorrectcredentialsexception:密码错误 */ e.printstacktrace(); system.out.println("用户名不存在"); }catch (incorrectcredentialsexception e){ system.out.println("密码错误"); } return "login"; } @requestmapping("/add") public string add(){//跳转页面 return "add"; } @requestmapping("/del") public string delete(){//跳转页面 return "delete"; } @requestmapping("/unauthorized") public string unauthorized(){//没有权限跳转的url return "unauthorized"; } //注销 @requestmapping("/logout") public string logout() { subject subject = securityutils.getsubject(); session session = subject.getsession(); session.setattribute("loginuser",null);//清空session return "login"; }
- 编写未授权的页面
unauthorized.html
- 运行:
root用户只有user:delete权限 所以只能看到删除按钮
dj用户只有user:add权限 只能看到添加
ss用户什么权限也没有 所以什么按钮也看不见
其中还有加密方式 比如md5 可以自行添加 就不一一介绍了
重点:shiroconfig类和userrealm类配置好 核心**
推荐阅读
-
详解springboot整合ehcache实现缓存机制
-
Springboot整合pagehelper分页功能
-
springboot整合ehcache 实现支付超时限制的方法
-
Springboot中集成Swagger2框架的方法
-
Spring+Hibernate+Struts(SSH)框架整合实战
-
springboot整合rabbitmq的示例代码
-
一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程
-
将Python的Django框架与认证系统整合的方法
-
Spring mvc整合tiles框架的简单入门教程(maven)
-
Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(图文)