Springboot-Shiro该怎么使用
发表于:2024-12-13 作者:千家信息网编辑
千家信息网最后更新 2024年12月13日,Springboot-Shiro该怎么使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、依据官网快速搭建Quickstart1.1
千家信息网最后更新 2024年12月13日Springboot-Shiro该怎么使用
Springboot-Shiro该怎么使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
一、依据官网快速搭建Quickstart
1.1 配置pom.xml依赖
org.apache.shiro shiro-core 1.7.1 org.slf4j jcl-over-slf4j 1.7.21 org.slf4j slf4j-log4j12 1.7.21 log4j log4j 1.2.17
1.2配置log4j.properties
log4j.rootLogger=INFO, stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n# General Apache librarieslog4j.logger.org.apache=WARN# Springlog4j.logger.org.springframework=WARN# Default Shiro logginglog4j.logger.org.apache.shiro=INFO# Disable verbose logginglog4j.logger.org.apache.shiro.util.ThreadContext=WARNlog4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
1.3 配置shiro.ini
[users]# user 'root' with password 'secret' and the 'admin' roleroot = secret, admin# user 'guest' with the password 'guest' and the 'guest' roleguest = guest, guest# user 'presidentskroob' with password '12345' ("That's the same combination on# my luggage!!!" ;)), and role 'president'presidentskroob = 12345, president# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'darkhelmet = ludicrousspeed, darklord, schwartz# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'lonestarr = vespa, goodguy, schwartz# -----------------------------------------------------------------------------# Roles with assigned permissions## Each line conforms to the format defined in the# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc# -----------------------------------------------------------------------------[roles]# 'admin' role has all permissions, indicated by the wildcard '*'admin = *# The 'schwartz' role can do anything (*) with any lightsaber:schwartz = lightsaber:*# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with# license plate 'eagle5' (instance specific id)goodguy = winnebago:drive:eagle5
1.4启动类
import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.session.Session;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.session.Session;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Quickstart { private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class); public static void main(String[] args) { //使用shiro.ini文件在类路径的根目录 // (file:和url:前缀分别从文件和url加载): Factoryfactory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //获取当前的用户对象Subject Subject currentUser = SecurityUtils.getSubject(); //通过当前用户拿到session Session session = currentUser.getSession(); session.setAttribute("someKey", "aValue"); String value = (String) session.getAttribute("someKey"); if (value.equals("aValue")) {// log.info("Retrieved the correct value! [" + value + "]"); log.info("Subject=>session [" + value + "]"); } //判断当前的用户是否被认证 if (!currentUser.isAuthenticated()) { //Token :令牌,没有获取,随机 UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); token.setRememberMe(true);//记住我 try { currentUser.login(token);//执行登录操作~ } catch (UnknownAccountException uae) {//用户名不存在 log.info("There is no user with username of " + token.getPrincipal()); } catch (IncorrectCredentialsException ice) {//密码不对 log.info("Password for account " + token.getPrincipal() + " was incorrect!"); } catch (LockedAccountException lae) {//用户被锁定的 log.info("The account for username " + token.getPrincipal() + " is locked. " + "Please contact your administrator to unlock it."); } // ... catch more exceptions here (maybe custom ones specific to your application? catch (AuthenticationException ae) {//认证异常 //unexpected condition? error? } } //say who they are: //print their identifying principal (in this case, a username): log.info("User [" + currentUser.getPrincipal() + "] logged in successfully."); //test a role: if (currentUser.hasRole("schwartz")) { log.info("May the Schwartz be with you!"); } else { log.info("Hello, mere mortal."); }//粗粒度 //test a typed permission (not instance-level) if (currentUser.isPermitted("lightsaber:wield")) { log.info("You may use a lightsaber ring. Use it wisely."); } else { log.info("Sorry, lightsaber rings are for schwartz masters only."); }//细粒度 //a (very powerful) Instance Level permission: if (currentUser.isPermitted("winnebago:drive:eagle5")) { log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " + "Here are the keys - have fun!"); } else { log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!"); } //all done - log out! currentUser.logout(); System.exit(0); }}
二、springboot结合shiro使用
2.1准备数据库
pom.xml添加依赖:
org.apache.shiro shiro-core 1.7.1 org.slf4j jcl-over-slf4j 1.7.21 org.slf4j slf4j-log4j12 1.7.21 log4j log4j 1.2.17 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0 mysql mysql-connector-java com.alibaba druid 1.2.5 org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.0 org.apache.shiro shiro-spring 1.7.1 org.springframework.boot spring-boot-starter-web org.thymeleaf thymeleaf-spring5 org.thymeleaf.extras thymeleaf-extras-java8time org.projectlombok lombok 1.18.16
2.2配置yaml
spring: datasource: username: root password: 123456 #假如时区报错了就增减一个时区的配置就ok了:servletTimezone=UTC url: jdbc:mysql://localhost:3306/security?servletTimezone=UTC&useUnicode=true&characterEncodeing=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource #Spring Boot 默认是不注入这些属性值的,需要自己绑定 #druid 数据源专有配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,stat:监控日志,log4j:日志记录,wall,预防sql注入 #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority #则导入log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: durid.stat.mergeSql=true;druid.stat.slowSqlMillis=500mybatis: mapper-locations: classpath:mapper/*.xml
使用thymeleaf写几个页面:
index.html
首页 首页
[[${msg}]]
login.html
Title 登录
add.html
Title add
update.html
Title update
三、实体类
package com.jsxl.pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class User { private int id; private String name; private String password; private String auth;}
3.1UserMapper即UserMapper.xml
package com.jsxl.mapper;import com.jsxl.pojo.User;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Repository;@Repository@Mapperpublic interface UserMapper { public User queryUserByName(String name);}
UserController(简单使用这里直接调用Mapper):
package com.jsxl.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.ui.Model;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class UserController { @RequestMapping({"/","/index"}) public String toIndex(ModelMap map){ map.put("msg","hello shiro"); 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"; } @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"; } } @RequestMapping("/noauth") @ResponseBody public String unauthorized(){ return "未经授权无法访问此页面"; }}
四、shiro的配置类
package com.jsxl.config;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;import java.util.Map;@Configurationpublic class ShiroConfig { //ShiroFilterFactoryBean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro内置过滤器 /* anon :无需认证就可以访问 autho:必须认证了才能访问 user:必须拥有 记住我 功能才能用 perms:拥有对某个资源的权限才能访问 role: 拥有某个角色权限才能访问 */ //设置一个过滤器链 点击源码看需要什么参数,由于是链表用LinkedHashMap 拦截 MapfilterChainDefinitionMap = new LinkedHashMap<>(); //授权 正常情况下 没有授权会跳到未授权的页面 filterChainDefinitionMap.put("/user/add","perms[user:add]"); filterChainDefinitionMap.put("/user/update","perms[user:update]");// filterChainDefinitionMap.put("/user/add","authc");// filterChainDefinitionMap.put("/user/update","authc"); filterChainDefinitionMap.put("/user/*","authc"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); //设置登录请求 bean.setLoginUrl("/toLogin"); //未授权页面 bean.setUnauthorizedUrl("/noauth"); return bean; } //DefaultWebSecurityManager 2 @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联UserRealm securityManager.setRealm(userRealm); return securityManager; } //创建realm 对象 ,需要自定义类 1 @Bean(name = "userRealm")//正常情况下我们的方法名就是他 public UserRealm userRealm(){ return new UserRealm(); } @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); }}
package com.jsxl.config;import com.jsxl.mapper.UserMapper;import com.jsxl.pojo.User;import com.jsxl.service.UserServiceImpl;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;//自定义的UserRealmpublic class UserRealm extends AuthorizingRealm { @Autowired UserMapper userMapper; @Override//授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行了=>授权doGrtAuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// info.addStringPermission("user:add"); //拿到当前登录的这个对象 Subject subject = SecurityUtils.getSubject(); User currentUser = (User)subject.getPrincipal();//拿到user对象 //设置当前登录的用户的权限 info.addStringPermission(currentUser.getAuth()); return info;//授权不能return null } @Override//认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行了=>认证doGrtAuthorizationInfo"); UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;//获取信息 全局关系 User user = userMapper.queryUserByName(userToken.getUsername()); Subject currentSubject = SecurityUtils.getSubject(); Session session = currentSubject.getSession(); session.setAttribute("LoginUser",user); if(user==null){ return null;//抛出异常 UnknownAccountException } //密码验证 shiro做 有可能会泄露 加密了 return new SimpleAuthenticationInfo(user,user.getPassword(),""); }}
五、启动类
package com.jsxl;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class ShiroSpringbootApplication { public static void main(String[] args) { SpringApplication.run(ShiroSpringbootApplication.class, args); }}
测试:
root用户
test用户
5.1SecurityUtils. getSubject()
SecurityUtils. getSubject()
,可以获得当前正在执行的Subject
. 一个Subject
就是一个应用程序的用户的安全。实际上称它为"User",但太多的应用程序拥有已经拥有自己的 User 类/框架的现有 API,我们不想与它们发生冲突。此外,在安全领域,该术语Subject实际上是公认的术语。
getSubject()
独立应用程序中的调用可能会Subject在特定于应用程序的位置返回基于用户数据的 ,并且在服务器环境(例如 Web 应用程序)中,它Subject
根据与当前线程或传入请求关联的用户数据获取。
Session session = currentUser.getSession();session.setAttribute( "someKey", "aValue" );
这Session
是一个特定于 Shiro 的实例,它提供了您习惯于使用常规 HttpSessions
的大部分内容,但还有一些额外的好处和一个很大的区别:它不需要 HTTP 环境!
看完上述内容,你们掌握Springboot-Shiro该怎么使用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!
用户
登录
配置
认证
密码
应用程序
数据
程序
应用
对象
方法
用户名
页面
安全
内容
权限
不对
实际
实际上
就是
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
宜安科技工业互联网
数据库不支持事务怎么回滚
湖北回收电脑服务器散热风扇
四方网络安全对话
防溺水网络安全班会记录
数据库技术最新概念
重庆九龙坡果蔬软件开发
高校网络安全月报
异步数据库连接池问题
网络安全学习感受50字
sql存在数据库中
网络安全技术的浅析
信息数据输入数据库自动化
沅江电力系统软件开发
wince支持哪些数据库
应用软件开发什么意思
收购二手服务器
网络安全法一般安全义务
长春服务器价格
网络技术应用选修三学生分析
数据库技术最新概念
服务器怎么打开硬盘管理
分布式数据库系统复制透明性
青少年在行动网络安全
戴尔r720服务器硬盘
徐州盛斗士软件开发有限公司
网络安全问题xxs等
软件开发工作人员的工作计划
数据库软件生成实体
南通工厂软件开发平台