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

如何通过Spring Security让/api/employees/{id}仅对对应ID员工开放?

如何配置Spring Security 6让/api/employees/{id}仅允许对应ID的员工访问

要实现/api/employees/{id}仅允许对应ID的员工(或管理员)访问,核心思路是对比JWT Token中的员工ID与路径变量ID,同时保留管理员的全访问权限。以下是具体实现步骤:

1. 确保JWT包含员工ID声明

在生成JWT Token时,需要将员工ID存入Token的claims中,示例代码如下(假设你的用户实体包含employeeId字段):

@Autowired
private JwtEncoder jwtEncoder;

public String generateToken(UserDetails userDetails) {
    YourUserEntity user = (YourUserEntity) userDetails; // 替换为你的用户实体类
    Map<String, Object> claims = new HashMap<>();
    
    // 存入角色信息(原逻辑保留)
    claims.put("roles", user.getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList()));
    // 新增:存入员工ID到claims
    claims.put("employeeId", user.getEmployeeId());

    JwtClaimsSet claimsSet = JwtClaimsSet.builder()
            .subject(user.getUsername())
            .issuedAt(Instant.now())
            .expiresAt(Instant.now().plusHours(24))
            .claims(claims)
            .build();

    return jwtEncoder.encode(JwtEncoderParameters.from(claimsSet)).getTokenValue();
}

2. 修改SecurityConfig的权限规则

在SecurityFilterChain配置中,为/api/employees/{id}添加基于SpEL表达式的权限校验:

@Bean
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.csrf(csrf -> csrf.disable()).authorizeHttpRequests(auth -> {
        auth.requestMatchers("/auth/**").permitAll();
        auth.requestMatchers("/api/employees").hasRole("ADMIN");
        // 核心规则:管理员可访问,或当前用户ID与路径ID匹配
        auth.requestMatchers("/api/employees/{id}").access("hasRole('ADMIN') or #id == authentication.principal.claims['employeeId'].toString()");
        auth.anyRequest().authenticated();
    });
    httpSecurity.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
    httpSecurity.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    return httpSecurity.build();
}

代码说明:

  • hasRole('ADMIN'):保留管理员对所有员工详情的访问权限
  • #id == authentication.principal.claims['employeeId'].toString():对比路径变量id与JWT中存储的employeeId(转换为字符串是因为路径变量默认是字符串类型,若你的employeeId是数字类型,需要统一类型避免匹配失败)
  • authentication.principal:在JWT认证场景下,此对象为Jwt实例,可直接通过claims获取自定义字段

3. 验证逻辑

  • 当普通员工访问/api/employees/123时,只有其JWT中的employeeId为123才能成功访问
  • 管理员用户(拥有ADMIN角色)可访问任意/api/employees/{id}端点
  • 未登录或ID不匹配的请求会被拦截,返回403权限不足

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:53:15