如何通过isAccessAllowed方法实现访问控制

如何通过isAccessAllowed方法实现访问控制

在Web应用开发中,确保用户的访问权限是至关重要的。本文将详细讲解一个自定义的 isAccessAllowed 方法是如何实现这一功能的。我们将逐步解析这段代码,并探讨它的安全性和实现细节。

相关框架和类简介

在开始详细解析代码之前,先简单介绍一下相关的框架和类。

  • Apache Shiro:一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。本文中的 isAccessAllowed 方法就是Shiro框架的一部分。
  • Subject:Shiro中的核心类,代表当前运行的用户。通过这个类可以获取用户的身份信息、权限信息等。
  • Principal:表示当前用户的身份信息,例如用户名或用户对象。
代码概述

以下是我们讨论的核心代码段:

@Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) {Subject subject = getSubject(servletRequest, servletResponse);Object principal = subject != null ? subject.getPrincipal() : null;Class<? extends User> userClass = getUserClass(servletRequest, servletResponse);if (principal != null && (userClass == null || !userClass.isAssignableFrom(principal.getClass()))) {return false;}return super.isAccessAllowed(servletRequest, servletResponse, mappedValue);
}
方法签名解析
  • @Override:表示这个方法重写了父类的方法。
  • ServletRequestServletResponse:分别表示HTTP请求和响应。
  • Object mappedValue:通常是Shiro配置中定义的值,用于辅助权限判断。
主要逻辑解析
  1. 获取当前用户

    Subject subject = getSubject(servletRequest, servletResponse);
    Object principal = subject != null ? subject.getPrincipal() : null;
    
    • getSubject 方法获取当前请求的用户。
    • 如果用户不为空,getPrincipal 方法获取用户的身份信息(通常是用户名或用户对象)。
  2. 获取请求的用户类型

    Class<? extends User> userClass = getUserClass(servletRequest, servletResponse);
    
    • getUserClass 方法获取当前请求对应的用户类型(例如会员、商家等)。
  3. 权限判断

    if (principal != null && (userClass == null || !userClass.isAssignableFrom(principal.getClass()))) {return false;
    }
    
    • 如果用户存在 (principal != null) 且请求的用户类型不为空 (userClass != null),并且当前用户的类型不是请求的用户类型 (!userClass.isAssignableFrom(principal.getClass())),则返回 false,表示不允许访问。
  4. 调用父类的权限判断

    return super.isAccessAllowed(servletRequest, servletResponse, mappedValue);
    
    • 如果上述条件不满足,则调用父类的 isAccessAllowed 方法进行进一步的权限判断。

安全性分析

principal 是通过 getSubject(servletRequest, servletResponse).getPrincipal() 获取的,它代表当前用户的身份信息。这个身份信息通常是在用户通过登录认证后,由后台系统(如Shiro)管理并存储的。

获取 principal 的过程:
  1. 用户登录

    • 用户在前端页面输入用户名和密码进行登录。
    • 后端验证用户名和密码正确后,会创建一个用户会话,并将用户信息(principal)存储在会话中。
  2. 获取 Subject

    • getSubject(servletRequest, servletResponse) 方法从当前请求中获取与会话关联的 Subject 对象。
    • Subject 对象包含当前用户的身份信息和权限信息。
  3. 获取 principal

    • subject.getPrincipal() 获取当前用户的身份信息。这个信息是在用户成功登录后存储在 Subject 中的,通常是由后台系统管理的用户对象或用户名。

安全措施(续)

  1. 会话管理(续):

    • 用户登录成功后,系统会为用户创建一个唯一的会话(Session),并将用户的身份信息(principal)存储在会话中。
    • 每次请求都会携带会话ID,系统根据会话ID获取存储的用户信息。
  2. Token认证

    • 使用JWT(JSON Web Token)等方式,在用户登录成功后生成一个Token,包含用户的身份信息。
    • 每次请求携带Token,后台会验证Token的有效性和完整性。
  3. 加密和签名

    • 身份信息和Token在传输过程中使用加密技术(如HTTPS)进行保护,防止被窃听或篡改。
    • 使用数字签名来确保Token的完整性和不可伪造性。
  4. HttpOnly和Secure标志

    • 设置会话Cookie的HttpOnly标志,防止JavaScript访问Cookie。
    • 设置Secure标志,确保Cookie只在HTTPS连接中传输。

示例代码

为了更好地理解 isAccessAllowed 方法的实现,这里提供一个完整的示例代码,包括如何获取和校验 principal

import org.apache.shiro.subject.Subject;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class CustomAccessControl extends SomeShiroFilterBaseClass {@Overrideprotected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) {Subject subject = getSubject(servletRequest, servletResponse);Object principal = subject != null ? subject.getPrincipal() : null;Class<? extends User> userClass = getUserClass(servletRequest, servletResponse);if (principal != null && (userClass == null || !userClass.isAssignableFrom(principal.getClass()))) {return false;}return super.isAccessAllowed(servletRequest, servletResponse, mappedValue);}// 获取用户类型的方法示例private Class<? extends User> getUserClass(ServletRequest request, ServletResponse response) {// 假设从请求中获取用户类型参数String userType = request.getParameter("userType");if ("member".equals(userType)) {return Member.class;} else if ("merchant".equals(userType)) {return Merchant.class;}return null;}
}

结语

通过以上分析和示例代码,我们详细介绍了如何通过 isAccessAllowed 方法实现访问控制,并且讨论了相关的安全性问题。为了确保Web应用的安全性,建议结合使用会话管理、Token认证、加密和签名等多种技术手段。

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

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

相关文章

gd32-DMA测试

1&#xff09;内存到内存 uint8_t srcBuf[8] {0,1,2,3,4,5,6,7}; uint8_t dstBuf[8]; void DMA_M2M_Test(void) { //DMA0测试中&#xff0c;内存到内存不可以&#xff0c;不知道什么情况&#xff1b; // dma_multi_data_parameter_struct dma_init_parameter; // rc…

MySQL数据库练习----简易药品管理系统

CREATE TABLE user (userId int(11) NOT NULL AUTO_INCREMENT COMMENT 用户ID,userName varchar(255) NOT NULL COMMENT 用户名,account varchar(255) NOT NULL COMMENT 账号,password varchar(255) NOT NULL COMMENT 密码,createtime datetime NOT NULL COMMENT 创建时间,PRIM…

《C语言深度解剖》(20):动态内存管理中的易错点和避坑指南

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏链接查看&…

智能推荐系统:技术解析与实践指南

智能推荐系统&#xff1a;技术解析与实践指南 背景与挖掘目标 在互联网信息爆炸的今天&#xff0c;用户在海量内容中筛选感兴趣的信息变得日益困难。因此&#xff0c;搜索引擎结合推荐系统的模式应运而生。本章节将深入探讨推荐系统&#xff0c;其核心目标如下&#xff1a; …

Mybatis动态sql标签

动态SQL标签简介: MyBatis的一个强大的特性之一通常是它的动态SQL能力。如果你有使用JDBC或其他相似框架的经验,你就明白条件地串联SQL字符串在一起是多么的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态SQL可以彻底处理这种痛苦。 Mybatis中实现动态sql的标签有&#x…

【Help】Ubuntu卸载原生版本python后图像化界面消失

1. 开机进入tty界面&#xff0c;登录账号和密码 2. ping www.baidu.com 检测网络连接 2.1 若出现菱形乱码&#xff0c;则修改语言位英文 LANG"en_US.UTF-8" LANGUAGE"en_US:en" 2.2 如果没有网络连接&#xff0c;则 查找可用wifi&#xff1a;nmcli dev …

【论文速读】|利用大语言模型实现现实世界代码的翻译:一项针对翻译到Rust语言的研究

本次分享论文&#xff1a;Towards Translating Real-World Code with LLMs: A Study of Translating to Rust 基本信息 原文作者&#xff1a;Hasan Ferit Eniser, Hanliang Zhang, Cristina David, Meng Wang, Maria Christakis, Brandon Paulsen, Joey Dodds, Daniel Kroeni…

Maven之介绍

目录 一、简介 &#xff08;2&#xff09;为什么学习Maven&#xff1f; 二、小结 一、简介 &#xff08;1&#xff09;Maven 是一个 Java 项目管理和构建工具。它可以定义项目结构、项目依赖&#xff0c;并使用统一的方式进行自动化构建&#xff0c;是Java项目不可缺少的工具…

《FFmpeg开发实战:从零基础到短视频上线》资源下载和内容勘误

资源下载 下面是《FFmpeg开发实战&#xff1a;从零基础到短视频上线》一书用到的工具和代码资源&#xff1a; 1、本书使用的FFmpeg版本为FFmpeg 5.1.2&#xff0c;也可在FFmpeg的github主页上下载最新的FFmpeg源码。 2、本书第12章使用的Android Studio版本为Android Studio D…

原装GUVCL-T10GD韩国GENICOM光电二极管紫外线传感器原厂代理商

深圳市宏南科技有限公司是韩国GenUV公司的原厂代理商&#xff0c;所售紫外线传感器均来自于原始生产厂商直接供货&#xff0c;非第三方转售。 GUVCL-T10GD 韩国GENICOM光电二极管光传感器 / 低亮度 / 紫外线 UV-C传感器 GUVCL-T10GD 采用基于氮化铟的材料 肖特基型 光电二极管…

Linux线程:基于环形队列RingQueue的生产消费者模型

目录 一、环形队列的概念及定义 二、POSIX信号量 三、RingQueue的实现方式 3.1RingQueue.hpp的构建 3.2Thread.hpp 3.3Main.cc主函数的编写 3.4Task.hpp function包装器的使用 一、环形队列的概念及定义 此处的环形队列并不是一个真正意义上的环&#xff0c;而是通过对容…

微信小程序之横向列表展示

效果图 参考微信小程序可看 代码&#xff1a; <view class"lbtClass"><view class"swiper-container"><scroll-view class"swiper" scroll-x"true" :scroll-left"scrollLeft"><block v-for"(six…

centos7.5 安装mongo客户端

参考&#xff1a; https://doc.hcs.huawei.com/zh-cn/usermanual/dds/dds_faq_0018.html https://www.cnblogs.com/zhaoyingjie/p/17784968.html mongo 和 mongosh 的区别database - Difference in mongo --version and mongosh --version - Stack Overflow mongoDB 5.0 之后…

node-sass install 失败

安装失败多数是因为下载失败&#xff0c;或者node版本不对&#xff0c;node版本不对可以通过nvm去管理node,下载不同版本的node,通过nvm去切换不同版本的node去兼容不同的项目。 这篇文档主要说明下载失败的问题如何解决&#xff1a; 可以通过npm config list 查看npm镜像源的…

4.1 四个子空间的正交性

一、四个子空间的正交性 如果两个向量的点积为零&#xff0c;则两个向量正交&#xff1a; v ⋅ w v T w 0 \boldsymbol v\cdot\boldsymbol w\boldsymbol v^T\boldsymbol w0 v⋅wvTw0。本章着眼于正交子空间、正交基和正交矩阵。两个子空间的中的向量&#xff0c;一组基中的向…

专业与学校的权衡。

一场考试落下帷幕&#xff0c;新的思考与选择悄然来临。对于每一位高考考生&#xff0c;学校和专业选择是开启大学新生活的两个前置必选项。分数受限的条件下&#xff0c;“鱼与熊掌不可兼得”&#xff0c;到底是选择一个心仪的专业还是选择一个知名度更高的学校&#xff1f;这…

Python多语言欧拉法和预测校正器实现

&#x1f4dc;流体力学电磁学运动学动力学化学和电路中欧拉法 &#x1f4dc;流体力学电磁学运动学动力学化学和电路中欧拉法示例&#xff1a;Python重力弹弓流体晃动微分方程模型和交直流电阻电容电路 ✒️多语言实现欧拉法和修正欧拉法 在数学和计算科学中&#xff0c;欧拉…

C# VTK 移动旋转

对vtk 场景中一个或多个选中物体进行移动旋转。 交互移动旋转坐标系 首先我们创建旋转的交互坐标系&#xff0c;三个移动Actor&#xff0c;三个旋转Actor&#xff0c;还需要4个定位坐标的小球Actor。 public class CoordinateActor 中添加Actor// 当前选中的Actorpublic vtkAc…

【华为OD机试】获取最大软件版本号(C++ Java JavaScript Python )

题目 题目描述 Maven 版本号定义,<主版本>.<次版本>.<增量版本>-<里程碑版本>,举例3.1.4-beta 其中,主版本和次版本都是必须的,主版本,次版本,增量版本由多位数字组成,可能包含前导零,里程碑版本由字符串组成。 <主版本>.<次版本>…

C语言---数据结构(1)--时间复杂和空间复杂度计算

1.什么是时间复杂度和空间复杂度 1.1算法效率 算法效率分为时间效率和空间效率 时间效率被称为时间复杂度&#xff0c;而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度&#xff0c;而空间复杂度主要衡量一个算法所需要的额外空间&#xff0c;在计算…