使用Shiro和JPA结合MySQL实现一个简易权限管理系统
- 互联网
- 2025-09-06 20:57:01

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.Driver spring.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 { @Bean public 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; } @Bean public SecurityManager securityManager(Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } @Bean public 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; } @Override protected 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; } @Override protected 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:// .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:// .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实现一个简易权限管理系统由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“使用Shiro和JPA结合MySQL实现一个简易权限管理系统”