Java里如何开发简易投票用户权限管理

来源:中国站长站作者:石川澪头衔:网络博主
导读:本期聚焦于小伙伴创作的《Java里如何开发简易投票用户权限管理》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java里如何开发简易投票用户权限管理》有用,将其分享出去将是对创作者最好的鼓励。

在投票类项目中,用户权限管理是保障系统安全的核心模块,通常需要区分普通投票用户、投票管理员、系统管理员等不同角色,限制不同角色的操作范围,比如普通用户只能参与投票,管理员可以创建投票、查看投票结果等。合理的权限设计能避免越权操作,提升系统的稳定性和安全性。

Java里如何开发简易投票用户权限管理

权限模型设计

简易投票权限管理可以采用RBAC(基于角色的访问控制)模型,核心包含三个实体:用户、角色、权限。用户和角色是多对多关系,角色和权限也是多对多关系,通过角色作为中间层关联用户和权限,降低权限分配的复杂度。

我们可以设计如下基础表结构:

  • 用户表(user):存储用户基本信息,包含用户id、用户名、密码等字段
  • 角色表(role):存储角色信息,包含角色id、角色名称、角色描述等字段
  • 权限表(permission):存储权限信息,包含权限id、权限标识、权限描述等字段
  • 用户角色关联表(user_role):存储用户和角色的对应关系
  • 角色权限关联表(role_permission):存储角色和权限的对应关系

核心实体类定义

首先定义对应的Java实体类,这里以MyBatis-Plus框架为例,实体类代码如下:

// 用户实体类
public class User {
    private Long id;
    private String username;
    private String password;
    // 用户关联的角色集合
    private List<Role> roles;

    // getter和setter方法省略
}

// 角色实体类
public class Role {
    private Long id;
    private String roleName;
    private String roleDesc;
    // 角色关联的权限集合
    private List<Permission> permissions;

    // getter和setter方法省略
}

// 权限实体类
public class Permission {
    private Long id;
    private String permissionKey;
    private String permissionDesc;

    // getter和setter方法省略
}

权限校验功能实现

我们可以使用Spring Security框架快速实现权限校验逻辑,首先配置Spring Security,定义不同角色对应的访问权限规则:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置自定义的用户详情服务,用于加载用户信息和权限
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 投票查看接口,普通用户和管理员都可以访问
                .antMatchers("/vote/view/**").hasAnyRole("USER", "ADMIN")
                // 投票提交接口,只有普通用户和投票管理员可以访问
                .antMatchers("/vote/submit").hasAnyRole("USER", "VOTE_ADMIN")
                // 投票创建接口,只有投票管理员和系统管理员可以访问
                .antMatchers("/vote/create").hasAnyRole("VOTE_ADMIN", "SYSTEM_ADMIN")
                // 投票结果统计接口,只有管理员可以访问
                .antMatchers("/vote/result/**").hasAnyRole("VOTE_ADMIN", "SYSTEM_ADMIN")
                // 其他请求需要认证
                .anyRequest().authenticated()
                .and()
                // 开启表单登录
                .formLogin()
                .and()
                // 关闭csrf防护,方便测试
                .csrf().disable();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

接下来实现自定义的用户详情服务,从数据库中加载用户的角色和权限信息:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 查询用户信息
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        // 查询用户的角色
        List<Role> roles = roleMapper.selectByUserId(user.getId());
        // 查询角色对应的权限
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            // 添加角色前缀,Spring Security默认角色需要以ROLE_开头
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
            // 查询角色的权限
            List<Permission> permissions = permissionMapper.selectByRoleId(role.getId());
            for (Permission permission : permissions) {
                authorities.add(new SimpleGrantedAuthority(permission.getPermissionKey()));
            }
        }
        // 返回Spring Security的User对象
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
        );
    }
}

自定义权限注解实现

如果需要在方法层面更灵活地控制权限,可以自定义权限注解,实现更细粒度的权限校验:

// 自定义权限校验注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequiresPermission {
    // 需要的权限标识
    String value();
}

然后实现对应的权限校验切面:

@Aspect
@Component
public class PermissionAspect {

    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(requiresPermission)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, RequiresPermission requiresPermission) throws Throwable {
        // 获取当前登录用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("用户未登录");
        }
        // 获取用户权限
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        String needPermission = requiresPermission.value();
        // 校验用户是否拥有对应权限
        boolean hasPermission = authorities.stream()
                .anyMatch(auth -> auth.getAuthority().equals(needPermission));
        if (!hasPermission) {
            throw new RuntimeException("没有操作权限");
        }
        // 有权限则执行原方法
        return joinPoint.proceed();
    }
}

使用时只需要在对应的方法上添加注解即可:

@RestController
@RequestMapping("/vote")
public class VoteController {

    // 只有拥有vote:create权限的用户可以访问
    @RequiresPermission("vote:create")
    @PostMapping("/create")
    public String createVote(@RequestBody Vote vote) {
        // 创建投票的逻辑
        return "创建投票成功";
    }
}

常见问题说明

  • 角色名称在Spring Security中默认需要添加ROLE_前缀,配置权限规则时需要注意前缀匹配问题
  • 密码存储必须使用加密方式,不要明文存储用户密码,这里使用BCryptPasswordEncoder进行加密
  • 如果需要动态修改权限,不需要重启服务,只需要更新数据库中的角色权限关联数据,下次用户登录时就会加载最新的权限信息

Java投票权限管理用户权限Spring_Security修改时间:2026-07-01 21:57:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。