我使用 Spring Boot 和管理员工和部门的数据库 (Postgres) 创建了一个 api。我正在使用 java 20、Spring Boot 3.0.1 和 Spring security 6,并且我创建了此端点“/api/employees”,仅供管理员访问,因为它返回数据库中的所有员工,并且我有此端点/api/employees/{id} 返回具有给定 id 的特定员工。 顺便说一句,我没有为员工或部门创建任何控制器,因为我使用了 HATEOES,这意味着它通过编写任何代码为我创建员工和部门的端点。 这是安全配置文件: ` 公共类 SecurityConfig {
private final RSAKeyProperties keys;
public SecurityConfig(RSAKeyProperties keys) {
this.keys = keys;
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
AuthenticationManager authManager(UserDetailsService detailsService) {
DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
daoProvider.setUserDetailsService(detailsService);
daoProvider.setPasswordEncoder(passwordEncoder());
return new ProviderManager(daoProvider);
}
@Bean
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf(csrf -> csrf.disable()).authorizeHttpRequests(auth -> {
auth.requestMatchers("/auth/**").permitAll(); // This will allow anyone to access this endpoint in
// order to Login or Signup
auth.requestMatchers("/api/employees").hasRole("ADMIN");
auth.requestMatchers("/api/employees/{id}");
auth.anyRequest().authenticated();
});
httpSecurity.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
httpSecurity.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return httpSecurity.build();
}
@Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withPublicKey(keys.getPublicKey()).build();
}
@Bean
JwtEncoder jwtEncoder() {
JWK jwk = new RSAKey.Builder(keys.getPublicKey()).privateKey(keys.getPrivateKey()).build();
JWKSource<SecurityContext> jwkSource = new ImmutableJWKSet<>(new JWKSet(jwk));
return new NimbusJwtEncoder(jwkSource);
}
@Bean
JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
jwtConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
return jwtConverter;
}
}`
我要问的是如何使此端点“/api/employees/{id}”仅可供具有相同id的员工访问?
我是 Spring Security 的新手,所以我找不到任何解决方案。
为了回答你的问题,我建议将业务逻辑绑定到你的id,比如说你有 employeeService 并且它在restClientController 中有 findByEmail 方法
代码示例如下
@GET("employee/{id}")
public Response getClient(@AuthHeader("Token") String token ) {
String email = /** code to get the user's email or something **/
try {
Employee employee = employeeService.findByEmail(email);
return Response
.ok(employee)
.build();
} catch (Exception e) {
/** exception logic **/
return Response.status(Response.status.ERROR).build();
}
}
你的方法业务逻辑(这是最低限度)会是这样的!
希望这有帮助。