如何通过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
相关产品推荐
相关产品推荐

