You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6授权失效:ROLE前缀重复引发403错误排查

Spring Boot 3 + Spring Security 6 授权配置异常问题

我在使用Spring Boot 3和Spring Security 6配置授权规则时遇到了异常,始终无法正常生效:

配置与初始问题

我通过以下代码配置授权规则:

http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/hello/**").hasRole("USER"));

登录后访问/hello/**接口时,始终收到403 Forbidden错误。

查看Spring Security DEBUG日志,发现认证后的权限信息如下:

2024-06-15T06:55:20.123+05:30 DEBUG 15236 --- [spring-authn-authz] [nio-8080-exec-4] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=com.nagpal.spring_authn_authz.config.EmployeeUserDetails@2af776cf, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=846F84FABBD0F9B98EFEF4DAAE047AA4], Granted Authorities=[USER]]]

日志明确显示已授予USER权限,但依然返回403。

尝试修复后的异常行为

根据资料查询,Spring Security的角色权限需要添加ROLE_前缀,于是我修改了EmployeeUserDetails的getAuthorities方法:

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<GrantedAuthority> authorities = new ArrayList<>();
    log.info("Adding role with ROLE_ appended");
    GrantedAuthority role = new SimpleGrantedAuthority("ROLE_" + employee.getRole());
    authorities.add(role);    
    return authorities;
}

修改后访问接口仍返回403,且日志显示权限前缀被重复添加:

2024-06-15T06:59:28.747+05:30 DEBUG 15236 --- [spring-authn-authz] [nio-8080-exec-4] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=com.nagpal.spring_authn_authz.config.EmployeeUserDetails@2af776cf, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=846F84FABBD0F9B98EFEF4DAAE047AA4], Granted Authorities=[ROLE_ROLE_USER]]]

相关代码

EmployeeUserDetails类

public class EmployeeUserDetails implements UserDetails {

    private Employee employee;

    public EmployeeUserDetails(Employee employee) {
        this.employee = employee;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        // log.info("Adding role with ROLE_ appended");
        GrantedAuthority role = new SimpleGrantedAuthority(/*"ROLE_" + */ employee.getRole());
        authorities.add(role);    
        return authorities;
    }

    @Override
    public String getPassword() {
        return employee.getPassword();
    }

    @Override
    public String getUsername() {
       return employee.getEmail();
    }

    // 省略UserDetails接口其他默认实现方法
}

Employee实体类

@Entity
@Data
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "employee_id")
    private int id;
    @Column
    private String email;
    @Column
    private String password;
    @Column
    private String role;
}

用户初始化代码

public void customUsers(UserDetailsManager detailsManager) { 

    Employee employee1 = new Employee();
    employee1.setEmail("user1@email.com");
    employee1.setPassword(passwordEncoder().encode("password"));
    employee1.setRole("USER");

    EmployeeUserDetails user1 = new EmployeeUserDetails(employee1);

    detailsManager.createUser(user1);

}

数据库数据

启动后Employee表中的数据如下:
Employee表数据

我无法理解这种行为:不在UserDetails中添加ROLE_前缀时,权限中完全没有该前缀;添加后却出现重复的ROLE_ROLE_前缀,导致授权始终失败,希望能得到解惑。

内容的提问来源于stack exchange,提问作者Bagira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:44:57