手机版网站制作模板,织梦如何做中英文网站,深圳小程序制作,精品课程网站的设计与实现文章目录 前言一、RBAC#xff08;Role-Based Access Control#xff0c;基于角色的访问控制#xff09;二、Java实现RBAC 权限的大概思路1. 添加依赖2. 配置MyBatis-Plus和数据源1. 添加依赖2. 实体类与Mapper接口UserMapper.java 3. 配置MyBatis-Plus4. 自定义UserDetails… 文章目录 前言一、RBACRole-Based Access Control基于角色的访问控制二、Java实现RBAC 权限的大概思路1. 添加依赖2. 配置MyBatis-Plus和数据源1. 添加依赖2. 实体类与Mapper接口UserMapper.java 3. 配置MyBatis-Plus4. 自定义UserDetailsService 3. 实体和Mapper数据库表设计JPA实体映射示例注意 4. 实现UserDetailsService5. JWT过滤器和认证逻辑6. Spring Security配置示例代码片段JWT工具类JWT过滤器Spring Security配置 7. 登录API实现 前言
前端学java用于记录学习AI辅助创作有错误之处欢迎交流指正。
一、RBACRole-Based Access Control基于角色的访问控制
RBACRole-Based Access Control基于角色的访问控制是一种流行的权限管理模型它通过角色作为用户与权限之间的中介实现了权限的灵活管理和动态分配。以下是RBAC动态权限控制的关键概念和特点
基本元素
用户(User)系统中的操作者可以是员工、客户等。 角色(Role)一组权限的集合定义了用户可以执行的操作。角色是根据业务需求和职责划分创建的如管理员、编辑、访客等。 权限(Permission)系统中定义的具体操作权利如读取文件、写入数据库、删除记录等。 动态权限控制的特点
灵活性用户与权限之间不直接关联而是通过角色作为中间层。当用户的角色发生变化时其权限随之改变无需逐一调整用户权限提高了管理效率。 细粒度控制允许为角色分配具体的权限实现对系统资源访问的细粒度管理。 易于维护角色的增删改直接影响相关用户的权限简化了权限调整的过程便于大规模系统的权限管理。 权限继承与组合可以定义角色之间的继承关系或者组合多个角色赋予单个用户以适应复杂的权限需求。 实时性动态权限控制意味着权限更改可以即时生效无需重启服务或重新登录增强了系统的实时响应能力。 实现机制
权限检查每次用户尝试访问资源或执行操作时系统都会检查用户所属角色是否有对应权限。 权限缓存为了提高性能通常会将权限信息缓存起来减少数据库的频繁访问。 动态加载权限配置可以在运行时动态加载和更新无需重启应用即可调整权限策略。 API网关与过滤器在微服务架构中常利用API网关或在服务内部设置权限过滤器来实现动态权限验证。 综上所述RBAC动态权限控制通过引入角色作为中间层实现了用户权限的灵活配置和高效管理是现代复杂系统中常见的权限管理模式。
二、Java实现RBAC 权限的大概思路
要在Java Spring Boot项目中结合Spring Security实现RBAC权限控制并使用MyBatis-Plus作为ORM工具以及JWT进行登录认证可以遵循以下步骤
1. 添加依赖
在pom.xml中添加Spring Security、MyBatis-Plus和JWT相关的依赖
dependencies!-- Spring Security --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-api/artifactIdversion0.11.2/version/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-impl/artifactIdversion0.11.2/versionscoperuntime/scope/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-jackson/artifactIdversion0.11.2/versionscoperuntime/scope/dependency!-- MyBatis-Plus --dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.x.x/version/dependency
/dependencies2. 配置MyBatis-Plus和数据源
使用MyBatis-Plus作为ORM工具可以简化MyBatis的使用提供更多的开箱即用的功能如自动分页、性能优化等。下面是使用MyBatis-Plus实现上述RBAC模型的示例。
1. 添加依赖
首先在项目的pom.xml中添加MyBatis-Plus的依赖
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.x.x/version !-- 使用最新版本 --
/dependency2. 实体类与Mapper接口
实体类保持不变依然是之前的User, Role, Permission。接下来使用MyBatis-Plus的BaseMapper接口来简化Mapper的编写。
UserMapper.java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface UserMapper extends BaseMapperUser {// 如果有特殊的查询需求可以在这里添加自定义方法
}同理为Role和Permission创建类似的Mapper接口
public interface RoleMapper extends BaseMapperRole {
}public interface PermissionMapper extends BaseMapperPermission {
}3. 配置MyBatis-Plus
在Spring Boot的配置文件application.yml或application.properties中配置MyBatis-Plus和数据源
mybatis-plus:global-config:db-config:id-type: autoconfiguration:map-underscore-to-camel-case: true # 开启下划线转驼峰命名规则mapper-locations: classpath:mapper/*.xml # 如果有自定义的XML映射文件需要配置此路径spring:datasource:url: jdbc:mysql://localhost:3306/your_db?useSSLfalseserverTimezoneUTCusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Driver4. 自定义UserDetailsService
由于MyBatis-Plus已经简化了数据访问层的操作我们可以直接在MyUserDetailsService中使用BaseMapper来查询用户及其关联的角色和权限
Service
public class MyUserDetailsService implements UserDetailsService {Autowiredprivate UserMapper userMapper;Autowiredprivate RoleMapper roleMapper;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user userMapper.selectOne(new QueryWrapperUser().eq(username, username));if (user null) {throw new UsernameNotFoundException(User not found with username: username);}ListGrantedAuthority authorities new ArrayList();ListRole roles userMapper.selectRolesByUserId(user.getId());for (Role role : roles) {authorities.add(new SimpleGrantedAuthority(ROLE_ role.getName()));// 通常情况下权限也会通过角色间接关联这里简化处理}return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);}
}注意上述示例中selectRolesByUserId方法假设是自定义扩展的因为MyBatis-Plus的BaseMapper默认不会包含多表关联查询。如果需要这样的关联查询你可以
直接在Mapper接口中定义该方法并编写对应的SQL推荐使用注解形式。或者如果复杂度高可以在Mapper接口中声明方法然后在对应的XML文件中编写SQL查询。
使用MyBatis-Plus可以大大减少模板代码提升开发效率但依然需要根据具体需求灵活定制SQL查询逻辑。
3. 实体和Mapper
定义用户、角色、权限的实体类及对应的MyBatis-Plus Mapper接口如之前讨论的那样。
为了实现RBAC模型我们通常需要设计至少三张数据库表用户表(users)、角色表(roles)和权限表(permissions)以及一张关联表(user_roles)来关联用户与角色另一张关联表(role_permissions)来关联角色与权限。下面是这些表的一个简单设计示例以及如何使用JPA进行映射。
数据库表设计 users 表 id (主键)username (用户名)password (密码通常存储的是哈希值) roles 表 id (主键)name (角色名如ADMIN, “USER”) permissions 表 id (主键)name (权限名如READ, “WRITE”) user_roles 表多对多关联表 user_id (外键关联users表的id)role_id (外键关联roles表的id) role_permissions 表多对多关联表 role_id (外键关联roles表的id)permission_id (外键关联permissions表的id)
JPA实体映射示例
以下是如何使用Spring Data JPA映射这些实体的例子
Entity
Table(name users)
public class User {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String username;private String password; // 应使用BCrypt等加密存储ManyToMany(cascade CascadeType.ALL, fetch FetchType.EAGER)JoinTable(name user_roles,joinColumns JoinColumn(name user_id, referencedColumnName id),inverseJoinColumns JoinColumn(name role_id, referencedColumnName id))private SetRole roles;// 构造函数、getter、setter省略
}Entity
Table(name roles)
public class Role {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String name;ManyToMany(mappedBy roles)private SetUser users;ManyToMany(cascade CascadeType.ALL, fetch FetchType.EAGER)JoinTable(name role_permissions,joinColumns JoinColumn(name role_id, referencedColumnName id),inverseJoinColumns JoinColumn(name permission_id, referencedColumnName id))private SetPermission permissions;// 构造函数、getter、setter省略
}Entity
Table(name permissions)
public class Permission {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String name;ManyToMany(mappedBy permissions)private SetRole roles;// 构造函数、getter、setter省略
}注意
上述代码中实体间的关联关系使用了ManyToMany注解并通过JoinTable指定了关联表的细节。fetch FetchType.EAGER表示关联数据会立即加载根据实际情况也可以设置为LAZY延迟加载。在实际应用中密码字段应该使用密码加密器如BCrypt处理后再存储而不是明文。还需实现UserDetailsService接口时利用上述实体直接从数据库加载用户信息包括其关联的角色和权限。
通过这种方式你可以有效地在Spring Security框架内实现基于角色的访问控制并利用数据库来持久化这些信息。
4. 实现UserDetailsService
创建自定义的UserDetailsService使用MyBatis-Plus查询用户信息并转换为Spring Security的UserDetails对象。
5. JWT过滤器和认证逻辑
创建一个JWT Token生成和解析的工具类。实现一个JWT过滤器继承自OncePerRequestFilter用于解析请求头中的JWT令牌验证用户身份并设置认证信息到Security上下文中。实现登录逻辑验证用户名和密码后使用JWT工具类生成Token并返回给客户端。
6. Spring Security配置
配置Spring Security禁用默认的表单登录添加JWT过滤器到过滤链中。定义访问控制规则使用PreAuthorize或PostAuthorize等注解在Controller的方法上实现细粒度的权限控制或者在Spring Security配置类中使用.authorizeRequests()来配置URL访问规则。
示例代码片段
JWT工具类
public class JwtTokenProvider {// 使用密钥生成Token的逻辑// 验证Token的逻辑
}JWT过滤器
public class JwtAuthenticationFilter extends OncePerRequestFilter {// 实现JWT的解析与用户认证逻辑
}Spring Security配置
Configuration
EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate JwtAuthenticationFilter jwtAuthenticationFilter;Overrideprotected void configure(HttpSecurity http) throws Exception {http http.csrf().disable();http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class).authorizeRequests().antMatchers(/login).permitAll().antMatchers(/admin/**).hasRole(ADMIN).antMatchers(/user/**).hasAnyRole(USER, ADMIN).anyRequest().authenticated();}
}7. 登录API实现
创建一个登录接口接收用户名和密码验证后生成JWT并返回。
以上步骤概括了使用Spring Security、MyBatis-Plus和JWT实现RBAC权限控制的基本流程。根据实际项目需求可能还需要进一步细化和调整。