0

我正在使用带有 Java 11 的 Spring Boot 2 和 Spring Security 11。我正在创建一个仅限 API 的应用程序并尝试保护与“用户”相关的端点......

@Configuration
@EnableWebSecurity
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .exceptionHandling().authenticationEntryPoint(jwtUnAuthorizedResponseAuthenticationEntryPoint).and()
                .sessionManagement().sessionCreationPolicy(
                        SessionCreationPolicy.STATELESS).and()
        .authorizeRequests()
        .antMatchers("/api/users").access("hasRole('ADMIN')")
        .anyRequest().authenticated();

        http
        .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        http
        .headers()
        .frameOptions().sameOrigin()
        .cacheControl(); //disable caching
    }

我有这个 RestController 供用户使用...

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public ResponseEntity<List<User>> find() {
        List<User> foundUsers = userService.find();
        return ResponseEntity.ok(foundUsers);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> read(@PathVariable("id") UUID id) {
        User foundUser = userService.findById(id);
        if (foundUser == null) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(foundUser);
        }
    }
    
    @PostMapping
    @ResponseStatus(code = HttpStatus.CREATED)
    public void create(@Valid @RequestBody User user) {
        userService.create(user);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> update(@RequestBody User card, @PathVariable UUID id) {
        final User updatedUser = userService.update(id, card);
        if (updatedUser == null) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(updatedUser);
        }
    }

}

如果他们登录的用户的 ID 与请求的 ID 匹配,我想扩展我的安全性以允许人们访问 GET 和 PUT 端点。是否可以在 HttpSecurity 中为此添加规则,或者我是否允许所有人访问这些端点,然后在 REST 方法中添加 Java 以检查已登录的用户?

4

1 回答 1

1

启用方法安全性并使用@PreAuthorize注释您要保护的控制器方法。@PreAuthorize允许定义一个 SpEL,它将被评估为布尔值,以查看是否允许执行该方法。

首先通过以下方式启用方法安全性@EnableGlobalMethodSecurity

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfiguration {
    

}

然后在控制器方法中:

@GetMapping("/{id}")
@PreAuthorize("principal.id = #id")
public ResponseEntity<User> read(@PathVariable("id") UUID id) {
 
}
  • 您可以使用#xxx来访问受保护方法的参数。
  • principal访问存储在SecurityContext. 这取决于您如何自定义用户对象。
  • 您还可以使用内置表达式authentication来访问Authentication对象以SecurityContext进行检查。
于 2020-06-27T04:10:07.163 回答