如何使用 Spring Security 使端点只能由具有该端点中包含的 id 的用户访问?

问题描述 投票:0回答:1

我使用 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 的新手,所以我找不到任何解决方案。

java spring-boot authentication spring-security authorization
1个回答
0
投票

为了回答你的问题,我建议将业务逻辑绑定到你的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();
       }

}

你的方法业务逻辑(这是最低限度)会是这样的!

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.