Search code examples
spring-bootspring-securityspring-security-oauth2

Validation error in controller returns 401 instead of 400


I have a post endpoint in my rest controller which is accessible without authentication/authorization. it is configured in WebSecurityConfigurerAdapter like this:

@Override
public void configure(WebSecurity web) {
    web.ignoring().antMatchers("/api/v1/user");
}

The endpoint has a validation of an input data (provided by annotation javax.validation.Valid). When I send invalid data, I receive 401 response instead of 400. This problem doesn't exist in secured endpoints, where the default spring boot 400 message is sent.

During debugging, I discovered that during handling the MethodArgumentNotValidException (which is thrown when the validation error occurs in the controller), the WebExpressionVoter is executed and returns value -1, which means 'access denied'. How can I configure my application to ignore security checks for endpoints, which are public?

I know that using ControllerAdvice for exception handling is one of the option, but is it possible to have default 400 messages?

Thanks in advance for any hints!

EDIT:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  OAuth2AuthenticationProcessingFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

Solution

  • Ok, I found the soulution. I don't why, but when an exception occurs, there is another POST request to this url: /error. When I added this url to my ignoring list then it started to work. So my configuration looks like this:

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/api/v1/user", "/error/**")
    }
    

    @Ken Chan thank you for the information about debuging filters! It was crucial.