当前位置: 首页 > news >正文

使用 Shiro 和 JPA 结合 MySQL 实现一个简易权限管理系统

1. 项目设置

首先,确保你的项目已经配置好 Maven 或 Gradle 依赖管理工具,并添加以下依赖:

Maven 依赖

<dependencies><!-- Shiro 核心库 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.9.0</version></dependency><!-- Shiro Web 支持 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.9.0</version></dependency><!-- JPA 支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><!-- Spring Boot Web 支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot 安全支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 其他依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
</dependencies>

2. 配置 MySQL 数据库

在 application.properties 或 application.yml 中配置 MySQL 数据库连接:

spring.datasource.url=jdbc:mysql://localhost:3306/shiro_demo
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

3. 创建实体类

使用 JPA 创建用户、角色和权限的实体类。

用户实体 (User)
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@ManyToMany(fetch = FetchType.EAGER)private Set<Role> roles;// Getters and Setters
}
角色实体 (Role)

@Entity
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@ManyToMany(fetch = FetchType.EAGER)private Set<Permission> permissions;// Getters and Setters
}
权限实体 (Permission)
@Entity
public class Permission {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;// Getters and Setters
}

4. 创建 Repository 接口

使用 Spring Data JPA 创建 Repository 接口。

public interface UserRepository extends JpaRepository<User, Long> {User findByUsername(String username);
}public interface RoleRepository extends JpaRepository<Role, Long> {
}public interface PermissionRepository extends JpaRepository<Permission, Long> {
}

5. 配置 Shiro

创建一个 Shiro 配置类,配置 Realm 和 SecurityManager。

@Configuration
public class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/logout", "logout");filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic SecurityManager securityManager(Realm realm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(realm);return securityManager;}@Beanpublic Realm realm(UserRepository userRepository) {return new JpaRealm(userRepository);}
}

6. 自定义 Realm

创建一个自定义的 Realm 类,用于从数据库中获取用户信息。

public class JpaRealm extends AuthorizingRealm {private final UserRepository userRepository;public JpaRealm(UserRepository userRepository) {this.userRepository = userRepository;}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal();User user = userRepository.findByUsername(username);SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();for (Role role : user.getRoles()) {authorizationInfo.addRole(role.getName());for (Permission permission : role.getPermissions()) {authorizationInfo.addStringPermission(permission.getName());}}return authorizationInfo;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();User user = userRepository.findByUsername(username);if (user == null) {throw new UnknownAccountException("User not found");}return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());}
}

7. 创建控制器

创建一个简单的控制器来处理登录和访问控制。

@Controller
public class HomeController {@GetMapping("/home")public String home() {return "home";}@GetMapping("/login")public String login() {return "login";}@PostMapping("/login")public String doLogin(@RequestParam String username, @RequestParam String password) {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);return "redirect:/home";} catch (AuthenticationException e) {return "redirect:/login?error";}}@GetMapping("/logout")public String logout() {Subject subject = SecurityUtils.getSubject();subject.logout();return "redirect:/login";}
}

8. 创建视图

创建简单的 Thymeleaf 视图来展示登录页面和主页。

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Login</title>
</head>
<body><h1>Login</h1><form th:action="@{/login}" method="post"><label for="username">Username:</label><input type="text" id="username" name="username" required><br><label for="password">Password:</label><input type="password" id="password" name="password" required><br><button type="submit">Login</button></form><p th:if="${param.error}" style="color: red;">Invalid username or password</p>
</body>
</html>

运行 HTML

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Home</title>
</head>
<body><h1>Welcome to the Home Page</h1><a th:href="@{/logout}">Logout</a>
</body>
</html>

9. 运行项目

启动 Spring Boot 应用程序,访问 http://localhost:8080/login 进行登录。登录成功后,你将能够访问 /home 页面。

10. 权限控制

你可以在控制器中使用 @RequiresRoles 或 @RequiresPermissions 注解来控制访问权限。

@Controller
public class AdminController {@RequiresRoles("admin")@GetMapping("/admin")public String admin() {return "admin";}
}

11、创建测试数据脚本

-- 插入权限数据
INSERT INTO permission (name) VALUES ('user:read');
INSERT INTO permission (name) VALUES ('user:write');
INSERT INTO permission (name) VALUES ('admin:read');
INSERT INTO permission (name) VALUES ('admin:write');-- 插入角色数据
INSERT INTO role (name) VALUES ('user');
INSERT INTO role (name) VALUES ('admin');-- 关联角色和权限
-- 用户角色拥有 user:read 和 user:write 权限
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'user'),(SELECT id FROM permission WHERE name = 'user:read')
);
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'user'),(SELECT id FROM permission WHERE name = 'user:write')
);-- 管理员角色拥有所有权限
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'admin'),(SELECT id FROM permission WHERE name = 'user:read')
);
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'admin'),(SELECT id FROM permission WHERE name = 'user:write')
);
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'admin'),(SELECT id FROM permission WHERE name = 'admin:read')
);
INSERT INTO role_permissions (role_id, permissions_id) VALUES ((SELECT id FROM role WHERE name = 'admin'),(SELECT id FROM permission WHERE name = 'admin:write')
);-- 插入用户数据
-- 密码使用 Shiro 的加密方式(例如 MD5 加密)
INSERT INTO user (username, password) VALUES ('user1', 'password1');
INSERT INTO user (username, password) VALUES ('admin1', 'password1');-- 关联用户和角色
-- 用户 user1 拥有 user 角色
INSERT INTO user_roles (user_id, roles_id) VALUES ((SELECT id FROM user WHERE username = 'user1'),(SELECT id FROM role WHERE name = 'user')
);-- 用户 admin1 拥有 admin 角色
INSERT INTO user_roles (user_id, roles_id) VALUES ((SELECT id FROM user WHERE username = 'admin1'),(SELECT id FROM role WHERE name = 'admin')
);

 测试登录

启动应用程序后,使用以下测试用户登录:

  • 用户user1,密码: password1,角色: user

  • 用户admin1,密码: password1,角色: admin

登录后,你可以根据角色和权限访问不同的页面。

相关文章:

使用 Shiro 和 JPA 结合 MySQL 实现一个简易权限管理系统

1. 项目设置 首先&#xff0c;确保你的项目已经配置好 Maven 或 Gradle 依赖管理工具&#xff0c;并添加以下依赖&#xff1a; Maven 依赖 <dependencies><!-- Shiro 核心库 --><dependency><groupId>org.apache.shiro</groupId><artifactI…...

DeepSeek与医院电子病历的深度融合路径:本地化和上云差异化分析

一、引言 1.1 研究背景与意义 在医疗信息化快速发展的当下,电子病历系统已成为医院信息管理的核心构成。电子病历(EMR)系统,是指医务人员在医疗活动过程中,使用医疗机构信息系统生成的文字、符号、图标、图形、数据、影像等数字化信息,并能实现存储、管理、传输和重现的…...

设计模式:代理模式

代理模式是很常见的设计模式&#xff0c;即使没有专门学习过这种设计模式&#xff0c;在工作中也一定用过这种设计模式。在实际生活中&#xff0c;代理模式也是常见的&#xff0c;比如内阁首辅相对于皇帝&#xff0c;前者是后者的代理&#xff0c;内阁首辅收到奏折时&#xff0…...

141,【1】buuctf web [SUCTF 2019]EasyWeb

进入靶场 代码审计 <?php // 定义函数get_the_flag&#xff0c;功能是处理文件上传相关操作 function get_the_flag() {// 注释说明&#xff1a;webadmin会每隔20分钟删除用户上传的文件$userdir "upload/tmp_" . md5($_SERVER[REMOTE_ADDR]);// 检查用户目录…...

破解微服务疑难杂症:2025年全解决方案

微服务架构已经成为现代软件开发的主流选择&#xff0c;其优势在于能够将复杂的系统拆分为独立的服务模块&#xff0c;方便开发和维护。然而&#xff0c;在微服务的实施过程中&#xff0c;开发者往往会面临许多挑战&#xff0c;如服务间通信、数据一致性、性能优化和故障处理等…...

Node.js 中的 Event 模块详解

Node.js 中的 Event 模块是实现事件驱动编程的核心模块。它基于观察者模式&#xff0c;允许对象&#xff08;称为“事件发射器”&#xff09;发布事件&#xff0c;而其他对象&#xff08;称为“事件监听器”&#xff09;可以订阅并响应这些事件。这种模式非常适合处理异步操作和…...

EasyRTC嵌入式WebRTC视频通话SDK支持Web浏览器、Linux、ARM、Android、iOS

随着互联网技术的飞速发展&#xff0c;实时通信&#xff08;RTC&#xff09;已经成为现代应用中不可或缺的一部分。无论是视频会议、在线教育、远程医疗&#xff0c;还是社交娱乐&#xff0c;实时通信技术都在其中扮演着重要角色。 然而&#xff0c;WebRTC技术在PC和移动端的支…...

pycharm社区版有个window和arm64版本,到底下载哪一个?还有pycharm官网

首先pycharm官网是这一个。我是在2025年2月16日9:57进入的网站。如果网站还没有更新的话&#xff0c;那么就往下滑一下找到 community Edition,这个就是社区版了免费的。PyCharm&#xff1a;适用于数据科学和 Web 开发的 Python IDE 适用于数据科学和 Web 开发的 Python IDE&am…...

【玩转全栈】----Django模板语法、请求与响应

目录 一、引言 二、模板语法 三、传参 1、视图函数到模板文件 2、模板文件到视图函数 四、引入静态文件 五、请求与响应 ?1、请求 2、响应 六、综合小案例 1、源码展示 2、注意事项以及部分解释 3、展示 一、引言 像之前那个页面&#xff0c;太过简陋&#xff0c;而且一个完整…...

网络安全:挑战、技术与未来发展

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 在数字化时代&#xff0c;网络安全&#xff08;Cybersecurity&#xff09;已成为全球关注的焦点。随着云计算、大数据、…...

DeepSeek 服务器繁忙的全面解决方案

目录 引文 正文 一、 服务器繁忙的原因分析 二、 解决方案 2.1切换网络 2.2使用网络加速工具 2.3错峰使用DeepSeek 2.4本地部署 2.5调用API 三、官方动态 一、技术研发与产品升级 二、市场合作与商业化进展 三、区域化布局与产业赋能 四、未来规划与社会责任 结语…...

将OpenWrt部署在x86服务器上

正文共&#xff1a;1234 字 40 图&#xff0c;预估阅读时间&#xff1a;2 分钟 如果你问ChatGPT有哪些开源的SD-WAN方案&#xff0c;他会这样答复你&#xff1a; 我们看到&#xff0c;OpenWrt也属于比较知名的开源SD-WAN解决方案。当然&#xff0c;在很久之前&#xff0c;我就发…...

计算机视觉:卷积神经网络(CNN)基本概念(一)

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络 一、引言 卷积神经网络&…...

企业文件共享中的权限管理与安全风险防范

在企业的日常运营中&#xff0c;文件共享是必不可少的一项工作。然而&#xff0c;文件共享过程中如果权限管理不当&#xff0c;极易引发安全风险&#xff0c;导致企业敏感信息泄露。因此&#xff0c;加强文件共享中的权限管理与安全风险防范&#xff0c;对于保障企业信息安全至…...

使用DeepSeek建立一个智能聊天机器人0.12

为了确保这段代码能够在Windows和Linux系统上都能正常运行,我考虑以下几个方面: 路径分隔符:在Windows和Linux中,文件路径的分隔符不同。Windows使用反斜杠(\),而Linux使用正斜杠(/)。我们可以使用 os.path.join 来处理路径,以确保跨平台兼容性。 消息框:tkinter.…...

国家队出手!DeepSeek上线国家超算互联网平台!

目前,国家超算互联网平台已推出 DeepSeek – R1 模型的 1.5B、7B、8B、14B 版本,后续还会在近期更新 32B、70B 等版本。 DeepSeek太火爆了!在这个春节档,直接成了全民热议的话题。 DeepSeek也毫无悬念地干到了全球增速最快的AI应用。这几天,国内的云计算厂家都在支持Dee…...

Deep seek学习日记1

Deepseek最强大的就是它的深度思考&#xff0c;并且展现了它的思考过程。 五种可使用Deep seek的方式&#xff08;应该不限于这五种&#xff0c;后续嵌入deepseek的应该更多&#xff0c;多了解一点因为官网容易崩~~&#xff09;&#xff1a; 1.deep seek官网 2.硅基流动silicon…...

乐理笔记(持续更新)

单音与音程 单音&#xff1a;由一个音组成。 音程&#xff1a;由两个音组成&#xff0c;表示两个音之间的音高距离。 如何数音程&#xff1a; 单音程&#xff1a;9 - X&#xff0c;性质相反。例如&#xff0c;9度音程减去某个数&#xff0c;性质会相反。 复音程&#xff1a…...

【动态路由】系统Web URL资源整合系列(后端技术实现)【nodejs实现】

需求说明 软件功能需求&#xff1a;反向代理功能&#xff08;描述&#xff1a;apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 业务应用等多个web资…...

PHP高效、轻量级表格数据处理库 OpenSpout ,很好用

OpenSpout 是一个高效、轻量级的 PHP 库&#xff0c;用于处理电子表格文件&#xff08;如 Excel 和 CSV&#xff09;。它支持读取和写入大型文件&#xff0c;且内存占用低。本文将详细介绍如何安装和使用 OpenSpout。 目录 安装 基本使用 高级功能 参考文档 安装 OpenSp…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...