Shiro应用到Web Application
一、权限基础
a) 认证(你是谁?)
判断你(被认证者)是谁的过程。通常被认证者提供用户名和密码。
常见的认证包含如下几种:
- 匿名认证:允许访问资源,不做任何类型的安全检查。
- 表单认证:访问资源之前,需要提交包含用户名和密码的表单。这是web application最常用的认证方式。这个过程一般会接合Session,只在第一次(新会话)访问资源时提交认证表单。
- 基本HTTP认证:基于RFC 2617的一种认证方式。
- 用户认证:Filter that allows access to resources if the accessor is a known user, which is defined as having a known principal. This means that any user who is authenticated or remembered via a 'remember me' feature will be allowed access from this filter.
b) 授权(你可以做什么?)
判断被认证者(你)是否能做什么操作的过程。
- 端口授权:必须通过指定的某个端口才能访问资源。
- Permission授权:Filter that allows access if the current user has the permissions specified by the mapped value, or denies access if the user does not have all of the permissions specified.
- Role授权:Filter that allows access if the current user has the roles specified by the mapped value, or denies access if the user does not have all of the roles specified.
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
c) 加密
使用技术手段(如:MD5、SHA等)把待加密的数据变为密文(如:信息摘要等)过程。
d) RBAC
基于角色的访问控制(Role-Based Access Control)。
e) Realm
data access object for an application’s security components (users,roles, permissions)
f) Permission
最小粒度的授权,不与用户关联。
例如:导出报表、查看id号为“PO20090008”的采购单、创建FAQ。
g) Role
Permission的集合。
二、Shiro特点
- 简单。
- 功能强大。
- 能独立运行,不依赖其它框架或容器。
- 包含了认证、授权、Session管理、加密。
- 易于扩展。
三、web application 集成Shiro
a) 数据模型

用户账号Account,可以简单的理解为用户。
一个账号可以拥有多个角色(Role)。
一个角色包含了多个权限(Permission)。
b) 创建工程,新建实体,添加与Shiro相关的Jar包
Eclipse:File--New--Other--Web--Dynamic Web Project
在 /WEB-INFO/lib/目录下添加如下Jar包

相关Jar包,http://incubator.apache.org/shiro/download.html
c) 配置web.xml,添加过滤器
<filter><filter-name>ShiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
</filter>
<filter-mapping><filter-name>ShiroFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
d) INI配置
[main]
#SHA256加密
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher#realm
myRealm = com.xx.xx.shiro.MyShiroRealm
myRealm.credentialsMatcher = $sha256Matcher#缓存
myRealm.authorizationCachingEnabled = true
cache=org.apache.shiro.cache.ehcache.EhCacheManager
myRealm.cacheManager=$cache[filters]
shiro.loginUrl = /login.jsp
#authc=org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.successUrl =/background.jsp
perms.unauthorizedUrl =/401.jsp[urls]
/login.jsp=authc
/logout.jsp=anon
/about.jsp=anon
/background.jsp=authc/faq/test.jsp=authc
/faq/list.jsp=authc,perms["faq:list"]
/faq/view.jsp=authc,perms["faq:view"]
位置:
配置参数可以写在web.xml文件中,也可以单独文件形式存放在本地类根路径、文件系统以及网络环境中。
Shiro INI Inline Config 和External Config
public class MyShiroRealm extends AuthorizingRealm {protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.fromRealm(getName()).iterator().next();if( username != null ){AccountManager accountManager = new AccountManagerImpl();Collection<Role> myRoles = accountManager.getRoles( username );if( myRoles != null ){SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();for( Role each:myRoles ){info.addRole(each.getName());info.addStringPermissions( each.getPermissionsAsString() );}return info;}}return null;}protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken ) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken;String accountName = token.getUsername();//用户名密码验证if( accountName != null && !"".equals(accountName) ){AccountManager accountManager = new AccountManagerImpl();Account account = accountManager.get( token.getUsername() );if( account != null )return new SimpleAuthenticationInfo(account.getName(),account.getPassword(), getName() );}return null;}
}
f) 登录页面
<%Object obj = request.getAttribute(org.apache.shiro.web.filter.authc.
FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);boolean flag = false;String msg = ""; if( obj != null ){if( "org.apache.shiro.authc.UnknownAccountException".equals( obj ) )msg = "未知帐号错误!";else if("org.apache.shiro.authc.IncorrectCredentialsException".equals( obj ))msg = "密码错误!"; else if( "org.apache.shiro.authc.AuthenticationException".equals( obj ))msg = "认证失败!";flag = !"".equals(msg);} if( flag )out.print( msg );
%><form action="login.jsp" method="post"><br/>用户帐号:<input type="text" name="username" id="username" value=""/><br/>登录密码:<input type="password" name="password" id="password" value="" /> <br/><input value="登录" type="submit" >
</form>
g) 登出页面
<%SecurityUtils.getSubject().logout();%>
四、在Shiro中实现CAPTCHA(验证码)功能
a) 验证码表单认证过滤器
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter{public static final String DEFAULT_CAPTCHA_PARAM = "captcha";private String captchaParam = DEFAULT_CAPTCHA_PARAM;public String getCaptchaParam() {return captchaParam;}protected String getCaptcha(ServletRequest request) {return WebUtils.getCleanParam(request, getCaptchaParam());}protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {String username = getUsername(request);String password = getPassword(request);String captcha = getCaptcha(request);boolean rememberMe = isRememberMe(request);String host = getHost(request); return new CaptchaUsernamePasswordToken(username, password, rememberMe, host,captcha);}
}
b) 用户名密码令牌UsernamePasswordToken
import org.apache.shiro.authc.UsernamePasswordToken;public classCaptchaUsernamePasswordToken extends UsernamePasswordToken {private static final long serialVersionUID = 1L;private String captcha;public String getCaptcha() {return captcha;} public void setCaptcha(String captcha) {this.captcha = captcha;}public CaptchaUsernamePasswordToken() {super();}public CaptchaUsernamePasswordToken(String username, char[] password,boolean rememberMe, String host,String captcha) { super(username, password, rememberMe, host);this.captcha = captcha;}
}
c) 添加AuthenticationException
public classIncorrectCaptchaException extends AuthenticationException{private static final long serialVersionUID = 1L;public IncorrectCaptchaException() {super();}public IncorrectCaptchaException(String message, Throwable cause) {super(message, cause);}public IncorrectCaptchaException(String message) {super(message);}public IncorrectCaptchaException(Throwable cause) {super(cause);}
}
d) Shiro INI文件
authc= com.xx.xx.shiro.CaptchaFormAuthenticationFilter
e) 实现Realm
protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken ) throwsAuthenticationException {CaptchaUsernamePasswordToken token = (CaptchaUsernamePasswordToken) authcToken;String accountName = token.getUsername();//验证码 验证String captcha = null;Object obj_captcha = SecurityUtils.getSubject().getSession().getAttribute( SessionKey.CAPTCHA );Object obj_count = SecurityUtils.getSubject().getSession().getAttribute( SessionKey.LOGIN_FAILED_COUNT );int failed_count = (obj_count == null || !(obj_count instanceof Integer))?0:(Integer)obj_count;if( obj_captcha instanceof String)captcha = (String)obj_captcha;if( captcha != null && failed_count >0&& !captcha.equalsIgnoreCase( token.getCaptcha() )){throw newIncorrectCaptchaException("验证码错误!");}//用户名密码验证if( accountName != null && !"".equals(accountName) ){AccountManager accountManager = newAccountManagerImpl();Account account = accountManager.get( token.getUsername() );if( account != null )return new SimpleAuthenticationInfo( account.getName(),account.getPassword(), getName() );}return null;}
}
f) 登录页面
<% Object obj = request.getAttribute(org.apache.shiro.web.filter.authc.
FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);boolean flag = false;String msg = ""; if( obj != null ){if( "org.apache.shiro.authc.UnknownAccountException".equals( obj ) )msg = "未知帐号错误!";else if("org.apache.shiro.authc.IncorrectCredentialsException".equals( obj ))msg = "密码错误!";else if("com.xx.xx.shiro.IncorrectCaptchaException".equals( obj ))msg = "验证码错误!";else if( "org.apache.shiro.authc.AuthenticationException".equals( obj ))msg = "认证失败!";flag = !"".equals(msg);}if( flag ){out.print( msg );Integer count = (Integer)request.getSession().getAttribute(SessionKey.LOGIN_FAILED_COUNT );if( count == null )count = Integer.valueOf(0);count++;request.getSession().setAttribute(SessionKey.LOGIN_FAILED_COUNT, count);}
%><form action="login.jsp" method="post"><br/>用户帐号:<input type="text" name="username" id="username" value=""/><br/>登录密码:<input type="password" name="password" id="password" value="" /> <br/>验证码:<input type="text" name="captcha" id="captcha" size="6"/><img src="/captcha" alt="captcha" /><br/><input value="登录" type="submit" >
</form>
g) CAPTCHA实现
h)
五、代码的开发环境
JAVA1.6
Tomcat
Eclipse
相关文章:
Shiro应用到Web Application
一、权限基础 a) 认证(你是谁?) 判断你(被认证者)是谁的过程。通常被认证者提供用户名和密码。 常见的认证包含如下几种: 匿名认证:允许访问资源,不做任何类型的安全检查。表单认证:访问资源之前,需要提…...
【POST请求-腾讯翻译君-爬虫案例】
原因:尝试多个在线翻译平台,由于返回数据存在加密原因(暂时不会解密),最总找到 ”腾讯翻译君“ 完成爬虫案例POST请求测试 案例测试网址 腾讯翻译 :https://fanyi.qq.com/ import requests import jsoncla…...
多卡片效果悬停效果
效果展示 页面结构 从页面的结构上看,在默认状态下毛玻璃卡片是有层次感的效果叠加在一起,并且鼠标悬停在卡片区域后,卡片整齐排列。 CSS3 知识点 transform 属性的 rotate 值运用content 属性的 attr 值运用 实现页面整体布局 <div …...
首饰饰品经营商城小程序的作用是什么
首饰如耳钉、戒指、手镯等除了高价值产品外,还有很多低价产品,市场需求客户众多,在实际经营中,商家们也会面临一些痛点。 私域话题越来越多加之线上线下同行竞争、流量匮乏等,更对商家选择自建商城经营平台。 通过【…...
华为OD机试真题【服务器能耗统计】
1、题目描述 【服务器能耗统计】 服务器有三种运行状态:空载、单任务、多任务,每个时间片的能耗的分别为1、3、4; 每个任务由起始时间片和结束时间片定义运行时间; 如果一个时间片只有一个任务需要执行,则服务器处于单任务状志; 如果一个时间片有多个任务需要执行,则服务器处于…...
ubuntu按下del却出现空格(命令行下键盘错乱)
问题: 有一天远程我的ubuntu 20.04,发现为何按 del 会产生空格后移的效果,up键也会重叠显示,首先感觉是这个远程软件有问题,于是又换了xshell,发现还是不行,只能打开积灰已久的笔记本࿰…...
Go开始:Go基本元素介绍
目录 标识符与关键字Go中的标识符Go关键字关键字示例 具名的函数常规函数代码示例 方法代码示例 高阶函数代码示例 匿名函数与Lambda表达式代码示例 闭包代码示例 具名的值变量基本数据类型复合数据类型指针类型 常量基本常量类型枚举常量常量表达式 定义类型和类型别名类型定义…...
十二、【漏洞复现】Rails任意文件读取(CVE-2019-5418)
十二、【漏洞复现】Rails任意文件读取(CVE-2019-5418) 12.1、漏洞原理 Ruby on Rails是一个使用 Ruby 语言写的开源 Web 应用框架,它是严格按照 MVC 结构开发的。它努力使自身保持简单,来使实际的应用开发时的代码更少,使用最少…...
【计算机视觉|人脸建模】学习从4D扫描中获取的面部形状和表情的模型
本系列博文为深度学习/计算机视觉论文笔记,转载请注明出处 标题:Learning a model of facial shape and expression from 4D scans 链接:Learning a model of facial shape and expression from 4D scans | ACM Transactions on Graphics Pe…...
【ADB】蓝牙总结
ADB 打开蓝牙关闭蓝牙打开Setting查看蓝牙地址查看蓝牙名称查看蓝牙是否开启车机蓝牙Setting配置路径wifi 打开蓝牙 adb root adb shell svc bluetooth enable 关闭蓝牙 adb root adb shell bluetooth disable 打开Setting adb shell am start -n com.android.settings/.S…...
嵌入式系统设计与应用---ARM处理器体系结构(学习笔记)
ARM处理器概述 Cortex-A8处理器工作模式 ps:除用户模式以外的其他模式被称为非用户模式或特权模式;除用户模式及系统模式以外的其他模式可称为异常模式 Cortex-A8存储器管理 ARM的基本数据类型 字节(Byte)&#…...
计算机竞赛 身份证识别系统 - 图像识别 深度学习
文章目录 0 前言1 实现方法1.1 原理1.1.1 字符定位1.1.2 字符识别1.1.3 深度学习算法介绍1.1.4 模型选择 2 算法流程3 部分关键代码 4 效果展示5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计 图像识别 深度学习 身份证识别…...
StarRocks数据导入
1、相关环境 Flink作为当前流行的流式计算框架,在对接StarRocks时,若直接使用JDBC的方式"流式"写入数据,对StarRocks是不友好的,StarRocks作为一款MVCC的数据库,其导入的核心思想还是"攒微批降频率&qu…...
JavaSE | 初识Java(一) | JDK \ JRE \ JVM
Java初识 Java 是一门半编译型、半解释型语言。先通过 javac 编译程序把源文件进行编译,编译后生成的 .class 文件是由字节 码组成的平台无关、面向 JVM 的文件。最后启动 java 虚拟机 来运行 .class 文件,此时 JVM 会将字节码转换成平台能够理…...
6轮面试阿里Android开发offer,薪资却从21k降到17k,在逗我?
一小伙工作快3年了,拿到了阿里云Android开发岗位P6的offer,算HR面一起,加起来有6轮面试了,将近3个月的时间,1轮同级 1轮Android用人部门leader 1轮Android 组leader 1轮项目CTO 1轮HR 1轮HRBP。 一路上各种事件分…...
基于混合蛙跳优化的BP神经网络(分类应用) - 附代码
基于混合蛙跳优化的BP神经网络(分类应用) - 附代码 文章目录 基于混合蛙跳优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.混合蛙跳优化BP神经网络3.1 BP神经网络参数设置3.2 混合蛙跳算法应用 4.测试结果…...
[架构之路-230]:计算机硬件与体系结构 - 可靠性、可用性、稳定性;MTTF、MTTR、MTBF
目录 一、软件质量属性 二、可靠性、可用性、稳定性区别 2.1 比较 2.2 公式比较 2.3 "正常工作时间"和"正常运行时间" 2.4 比较案例 2.5 可用性好但可靠性较差的示例 三、MTTF、MTTR、MTBF 3.1 图示 3.2 定义 (1)MTTF&am…...
selenium自动化测试环境安装教程
0X00前言: Selenium是一个广泛应用于Web应用程序测试的工具。它提供了一组功能强大的API,用于模拟用户与Web浏览器的交互。以下是对Selenium的简要介绍: 功能:Selenium能够自动化执行各种Web浏览器上的操作,如点击、输…...
如何修改springboot项目启动时的默认图标?
如下所示为springboot项目启动时的默认图标,我们可以把它换成我们自己喜欢的图片 方法如下: 第一步:我们需要将图片放置当前项目的resources目录下 如下所示为我自定义的一张照片 第二步: 方法1:在application.properties文件中…...
基于阴阳对优化的BP神经网络(分类应用) - 附代码
基于阴阳对优化的BP神经网络(分类应用) - 附代码 文章目录 基于阴阳对优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.阴阳对优化BP神经网络3.1 BP神经网络参数设置3.2 阴阳对算法应用 4.测试结果&#x…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...
Java高级 |【实验八】springboot 使用Websocket
隶属文章:Java高级 | (二十二)Java常用类库-CSDN博客 系列文章:Java高级 | 【实验一】Springboot安装及测试 |最新-CSDN博客 Java高级 | 【实验二】Springboot 控制器类相关注解知识-CSDN博客 Java高级 | 【实验三】Springboot 静…...
