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…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...