Spring Security 数据库认证场景下角色校验持续失败问题求助
问题原因
Spring Security的hasRole()、hasAnyRole()权限校验方法会默认给传入的角色拼接ROLE_前缀,再和用户的权限列表做匹配。你当前的权限校验逻辑和存储的权限值不匹配,是触发403的核心原因,和你使用MyBatis没有关联,因为你当前使用Spring Security原生JDBC认证直接走DataSource查询,不会经过MyBatis逻辑。
解决方案
你可以任选以下任意一种方案适配:
- 方案1:修改数据库
authorities表的authority字段值,给原有角色加上ROLE_前缀,比如CREATOR改为ROLE_CREATOR、USER改为ROLE_USER,符合Spring Security默认约定,无需修改代码。 - 方案2:保留数据库存储的权限值不变,将代码中的
hasRole()替换为hasAuthority()、hasAnyRole()替换为hasAnyAuthority(),这两个方法会直接做字符串匹配,不会自动拼接前缀:
// 修改前 .antMatchers("/createTrack").hasRole("CREATOR") // 修改后 .antMatchers("/createTrack").hasAuthority("CREATOR") // 修改前 .antMatchers("/getTrack").hasAnyRole("CREATOR", "USER") // 修改后 .antMatchers("/getTrack").hasAnyAuthority("CREATOR", "USER")
- 方案3:保留数据库存储和
hasRole()写法不变,给JDBC认证添加权限前缀配置,查询到的权限会自动拼接ROLE_前缀:
auth.jdbcAuthentication() .dataSource(dataSource) .usersByUsernameQuery("SELECT username,password,enabled FROM users WHERE username=?") .authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username=?") .rolePrefix("ROLE_"); // 新增这行配置
验证方法
你可以在测试接口中添加如下代码,打印当前登录用户的实际权限列表,确认权限值和校验逻辑是否匹配:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); System.out.println("当前用户权限:" + authentication.getAuthorities());
内容的提问来源于stack exchange,提问作者cr542
相关产品推荐
相关产品推荐

