SpringBoot整合Shiro权限框架

前言

在系统管理中,权限是非常重要的一个环节。目前权限框架中使用比较多的有Shiro、Spring Security。🎃
本篇简单写一下SpringBoot整合Shiro权限框架小栗子🌰。

个人博客地址:SpringBoot整合Shiro权限框架

介绍Shiro

Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架,Shiro 要简单的多。++更多详细介绍参考:w3cschool-shiro++

🚀开始

创建项目就不多嗦了,直接上干货~~

相关依赖

<!-- web依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><!-- 剔除spring logging依赖,防止与log4j2冲突 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
<!-- log4j依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- shiro 安全框架-->
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.6.0</version>
</dependency>

系统配置

shiro权限的主要配置部分分为:

  • subject(可以认为是一个认证对象,与当前应用交互的任何东西都是subject)
  • securityManager(安全管理器,所有安全相关的东西都是跟它交互的,它管理着所有的subject)
  • realm(可以认为是一个安全信息数据源,主要通过校验subject是否符合安全策略。所以我们在使用shiro时,需要先配置自己的realm)。

配置Realm

话不多说上代码~ 这里先以登录认证作为粟子

@Slf4j
public class MyShiroRealm extends AuthorizingRealm {@Resourceprivate SysUserService sysUserService;/*** 授权信息配置* @param principals* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 主要以登录认证作为例子, 此处暂时不做认证, 之后例子做补充return null;}/*** 登录认证信息* @param token token* @return 认证信息* @throws AuthenticationException e*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 返回认证信息, 一般为用户名Object principal = token.getPrincipal();if (ObjectUtil.isNull(principal)) {return null;}// 获取数据库中用户信息String loginName = principal.toString();SysUser user = sysUserService.findSysUserByName(loginName);if (null == user) {log.debug("{} - 登录用户不存在!", loginName);throw new UnknownAccountException("登录用户不存在!");}// 使用盐加密 构造方法ByteSource credentialsSalt = ByteSource.Util.bytes(loginName);;SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getLoginPwd(), credentialsSalt, getName());// 验证信息//SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getLoginPwd(), getName());log.debug("验证登录信息: {} ===>>>> {}", loginName, simpleAuthenticationInfo.getPrincipals());return simpleAuthenticationInfo;}
}

配置安全策略

增加完Realm域配置,我们需要让此配置生效,所以需要将它添加给Shiro的安全管理策略。

/*** 自定义安全管理策略*/
@Bean
public SecurityManager securityManager(MyShiroRealm myShiroRealm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置自定义的realmsecurityManager.setRealm(myShiroRealm);return securityManager;
}
/*** 地址过滤器** @param securityManager* @return*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 设置安全管理shiroFilterFactoryBean.setSecurityManager(securityManager);// 设置登录地址shiroFilterFactoryBean.setLoginUrl("/login");// 设置主页地址shiroFilterFactoryBean.setSuccessUrl("/index");// 设置未授权的urlshiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 开放登录接口filterChainDefinitionMap.put("/doLogin", "anon");// 生成验证码接口filterChainDefinitionMap.put("/captcha/captchaImg", "anon");// 开放静态资源文件filterChainDefinitionMap.put("/assets/**", "anon");// 其余url全部拦截,必须放在最后filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;
}/*** shiro生命周期* @return*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();
}/*** shiro注解启用配置* @return*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);return defaultAdvisorAutoProxyCreator;
}/**** @param securityManager* @return*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();sourceAdvisor.setSecurityManager(securityManager);return sourceAdvisor;
}

登录

设置完自定义域,以及自定义策略我们shiro就可以进行下一步了,那就是接口认证操作,这里简单定义一个接口

/*** 登录操作** @param loginName 登录名* @param loginPwd  登录密码* @return url*/
@ResponseBody
@PostMapping("/doLogin")
public Result<String> doLogin(String loginName, String loginPwd, String captcha, boolean rememberMe, HttpServletRequest request) {// 验证码校验String sessionCaptcha = (String) request.getSession().getAttribute(AppConstants.CAPTCHA_KEY);if (!StringUtils.equalsIgnoreCase(captcha, sessionCaptcha)) {return Result.error("验证码不匹配!");}UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginName, loginPwd, rememberMe);Subject subject = SecurityUtils.getSubject();try {// 认证操作subject.login(usernamePasswordToken);// 获取登录的用户SysUser user = (SysUser) subject.getPrincipal();// 将用户信息存入cookie中Session session = subject.getSession();session.setAttribute("user", user);// 删除session验证码request.getSession().removeAttribute(AppConstants.CAPTCHA_KEY);} catch (UnknownAccountException e) {log.debug("未知用户! {}", e.getMessage());return Result.error("未知用户!");} catch (IncorrectCredentialsException e) {log.debug("{} - 用户登录密码校验异常! {}", loginName, e.getMessage());return Result.error("密码校验异常!");} catch (AuthenticationException e) {log.debug("{} - 用户登录认证失败! {}", loginName, e.getMessage());return Result.error("登录失败!");} catch (Exception e) {log.debug("{} - 用户登录异常! {}", loginName, e.getMessage());return Result.error("登录异常!");}return Result.success("登录成功!");
}

测试

接口定义完,我们需要一个登录页面来完成登录认证操作,这里使用我之前写的登录页面来完成。
在这里插入图片描述

点击登录后观察接口执行情况:
在这里插入图片描述
当执行到subject.login()方法后,会进行认证操作,这时候就会执行到我们设置的自定义Realm。红框处是我们做完登录用户与数据库中比对过后,将用户信息存到了认证信息中并返回给接口。
在这里插入图片描述

最后页面成功跳转至新页面,我们就完成了登录认证操作啦。🕛

END

简单的完成了一个登录认证的操作,之后会慢慢更新shiro的其他功能😀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java开发必须掌握的8种网站攻防技术

转载自 Java开发必须掌握的8种网站攻防技术 XSS攻击 XSS攻击的全称是跨站脚本攻击(Cross Site Scripting),是WEB应用程序中最常见到的攻击手段之一。跨站脚本攻击指的是攻击者在网页中嵌入恶意脚本程序, 当用户打开该网页时,脚本程序便开始在客户端的浏览器上执行,以盗取客户端…

转:json与map互转

转自&#xff1a; java中字符串&#xff0c;json&#xff0c;Map互相转换&#xff08;各种转换都有&#xff09;_蜗牛驿站-CSDN博客_java json转map前提&#xff1a;使用jar包为fastjsonimport com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject; 程序如下: …

专属微信二维码python制作_如何利用Python制作简单的公众号二维码关注图

创意配图&#xff1a;微信&#xff0c;微信公众号&#xff0c;微信大V 而且最近发现了一个新的图像处理方面的库—Wand&#xff0c;它是 ImageMagick 库的 Python 接口。于是&#xff0c;我就打算用这个库来实现简单的制作一个二维码关注图&#xff0c;主要是完成以下几个工作&…

如何迁移#SNMP到.NET Core平台的一些体会

.NET Core 依然在飞速进化中&#xff0c;所以如果不是非常喜欢折腾的性格&#xff0c;建议各位还是暂时忍耐。 准备阶段 首先&#xff0c;Visual Studio 2015是必要的开发工具。虽然它已经包含了.NET Core的原始测试版&#xff0c;这里还是推荐下载 RC1 安装包&#xff0c; htt…

JAVA实现一个图片上传预览功能

这个小项目主要使用java实现了一个简单的图片上传预览功能&#xff0c;废话不多说&#xff0c;先上实现成果 ^ _ ^&#x1f4af; 预览 登录页 主页 上传页 图片预览 项目架构 后端: SpringBoot shiro mybatis-plus druid hutool 前端: layui viewer 项目结构 ├─src├…

小程序执行运行过程原理_PLC的基础小知识!不用把PLC想的太难

PLC实质上是工业计算机&#xff0c;是计算机技术与传统继电接触器控制器技术相结合的产物&#xff0c;只不过比一般的计算机具有更强的与工业过程相连接的接口和更直接的适用于工业控制要求的编程语言。一、PLC的结构从硬件结构上看&#xff0c;PLC主要由中央处理单元(CPU)、存…

内部局域网可自行分配的ip地址

【1】有些ip地址很特殊 以 10. 、 172.16. 、172.31. 、192.168. 开头的所有ipv4地址都未分配。 更确切的说&#xff0c;这些地址不会被 ISP&#xff08;Internet服务提供商&#xff09;分配给广域网上的计算机&#xff0c;即无法加入全球Internet网络-广域网&#xff1b; 但…

以吃货的角度理解 IaaS,PaaS,SaaS 是什么

转载自 以吃货的角度理解 IaaS&#xff0c;PaaS&#xff0c;SaaS 是什么随着云计算时代的到来&#xff0c;越来越多的软件&#xff0c;开始采用云服务。越来越多的概念也随之而来。云服务只是一个统称&#xff0c;可以分成三大类。IaaS&#xff1a;基础设施服务&#xff0c;Inf…

.Net使用RabbitMQ详解

序言 这几天呢&#xff0c;公司风波再起&#xff0c;去年一年公司CTO换啦4任&#xff0c;CEO换啦三个&#xff0c;这不刚来个新老大&#xff0c;感觉还不错&#xff0c;却没干过3个月又要走&#xff0c;索性趁老大们走来走去的时候&#xff0c;就给自己空出来&#xff0c;稍稍总…

SpringBoot整合Redis要注意的那些

前言 昨天自己在重新学习SpringBoot整合Redis时&#xff0c;遇到了一个问题java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig&#xff0c;错误很明显找不到需要的类。下面主要记录一下错误是怎么出线的&#xff0c;并且如何解决。 错…

Java之Socket与HTTP区别

转自&#xff1a; Java之Socket与HTTP区别 - 曹刚 - 博客园我们都知道TCP/IP协议共分四层&#xff1a;①链路层&#xff0c;有时也称作数据链路层或网络接口层&#xff0c;通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆&#xff08;或其他…

人人都能掌握的Java服务端性能优化方案

转载自 人人都能掌握的Java服务端性能优化方案 作为一个Java后端开发&#xff0c;我们写出的大部分代码都决定着用户的使用体验。如果我们的代码性能不好&#xff0c;那么用户在访问我们的网站时就要浪费一些时间等待服务器的响应。这就可能导致用户投诉甚至用户的流失。 关于性…

python模板模式_python-模板方法模式

说明&#xff1a; 模板方法模式时行为模式中比较简单的设计模式之一。模板方法关注这样的一类行为&#xff1a;该类行为在执行过程中拥有大致相同的动作次序&#xff0c;只是动作在实现的具体细节上有所差异。例如&#xff1a;泡茶和泡咖啡&#xff0c;泡茶&#xff1a;把水煮沸…

nacos启动失败:org.springframework.boot.web.server.WebServerExceptio

准备环境 系统环境: windows nacos: 2.0.0-BETA 错误信息 org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat 配置文件…

post使用form-data和x-www-form-urlencoded的本质区别

转自&#xff1a; post使用form-data和x-www-form-urlencoded的本质区别_null-CSDN博客一是数据包格式的区别&#xff0c;二是数据包中非ANSCII字符怎么编码&#xff0c;是百分号转码发送还是直接发送一、application/x-www-form-urlencoded1、它是post的默认格式&#xff0c;…

使用Nancy打造TaskManager2.0管理系统

上一篇开源任务管理平台TaskManager介绍发布后&#xff0c;有网友联系我看看能不能做个后台管理界面&#xff0c;方便管理系统中所有的任务。由于时间和技术问题1.0版本的时候&#xff0c;新增了一个3分钟读取配置文件动态修改任务的功能&#xff0c;不过总体来说还是不直观&am…

Java对象的序列化与反序列化

转载自 Java对象的序列化与反序列化 序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个储存媒介&#xff0c;例如档案或是记亿体缓冲等。在网络传输过程中&#xff0c;可以是字节或是XML等格式。而字节的…

网站能拿到其他网站的cookie_网站能给公司带来哪些好处?

事实上&#xff0c;许多企业仍在努力建立一个网站&#xff0c;因为如果它建立起来&#xff0c;它需要一笔钱和其他费用。但此时客户业务不太好&#xff0c;企业客户需要考虑很多问题&#xff0c;但创建网站的企业已经尝到了甜头。其实有些朋友可能会有一些偏差。例如&#xff0…

笨办法学习@ConditionalOnProperty 烧脑配置记录

前言 今天继续学习springboot时&#xff0c;一不小心就被ConditionalOnProperty注解的配置真假搞得我真的变得真真假假了。。&#xff08;此为真&#xff0c;彼为假&#xff0c;到底你是真还是你是假&#xff0c;晕了晕了。。。&#xff09; 本片主要记录一下注解的真假情况 …

javaI/O流小结

【README】 1.本文总结java IO读取或写入数据的方式和相关类说明&#xff1b; 2.java IO建立在流之上的。输入流读取数据&#xff0c;输出流写入数据&#xff1b; 3.过滤器流-filter stream&#xff0c;可以串连&#xff08;修饰&#xff09;到输入流和输出流上&#xff1b;…