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…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...