【问题标题】:ResponseStatusException is never returned back to userResponseStatusException 永远不会返回给用户
【发布时间】:2019-01-01 01:30:13
【问题描述】:

我有一个 Spring Boot Rest API,它在允许请求通过所请求的方法之前进行一些验证过滤。当它到达请求的端点时,我会对发送到服务器的数据进行一些验证,如果数据格式不正确,我希望返回一个 BAD REQUEST 响应。但是尝试抛出 Springs ResponseStatusException 不起作用,而是总是返回 403 Forbidden,我不知道为什么。

@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
JWTUtility jwtUtility;
@Autowired
UserRepository repository;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .addFilter(new JWTAuthenticationFilter(authenticationManager(), jwtUtility, repository))
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Override
public void configure(WebSecurity web) throws Exception {
    web
            .ignoring()
            .antMatchers(HttpMethod.POST, "/users");
}
}

.

@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {
private final UserRepository repository;
private final Pbkdf2PasswordEncoder passwordEncoder;

UserController(UserRepository repository, Pbkdf2PasswordEncoder passwordEncoder, JWTUtility jwtUtility) {
    this.repository = repository;
    this.passwordEncoder = passwordEncoder;
    this.jwtUtility = jwtUtility;
}

@PostMapping
User create(@RequestBody User user) {
    if (user.getFirstName() == null || user.getFirstName().isEmpty()
            || user.getLastName() == null || user.getLastName().isEmpty()
            || user.getEmail() == null || user.getEmail().isEmpty()
            || user.getDisplayName() == null || user.getDisplayName().isEmpty()
            || user.getPassword() == null || user.getPassword().isEmpty()) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "First name, last name, email, display name, and password must be provided when creating a new user.");
    }
    if (repository.findByEmail(user.getEmail()) != null) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with that email already exists");
    }
    if (repository.findByDisplayName(user.getDisplayName()) != null) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with that display name already exists");
    }

    user.setId(0);
    user.setPassword(passwordEncoder.encode(user.getPassword()));

    repository.save(user);

    return user;
}
}

我希望错误的请求会通过我提供的描述返回给用户。 Spring是否在某个地方拦截了这个?我该如何阻止它。

【问题讨论】:

  • 你能打印你的rest服务的堆栈异常吗?
  • 这很奇怪,它不会在任何地方生成堆栈跟踪。一旦它击中我的投掷,它只会返回 403。
  • 注释掉 @EnableWebSecurity 会导致它永远不会到达我的端点,而只会返回 401 Unauthorized。

标签: spring-boot spring-security exception-handling


【解决方案1】:

原来这是安全配置的问题,而我在 Web 安全配置中忽略了 /users 端点,允许请求通过该方法,显然在该方法中抛出异常导致 http 安全获取介入并拦截。

因此,将我的 http 安全更改为如下所示,

http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/users").permitAll()
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager(), jwtUtility, repository))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

解决了这个问题。奇怪的是它的行为是这样的,因为如果请求成功并且我不需要抛出异常,则用户对象返回就好了。看来抛出异常导致它不仅要注意网络安全,还要注意http安全。

【讨论】:

    猜你喜欢
    • 2019-11-15
    • 2011-07-25
    • 1970-01-01
    • 2012-10-02
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多