401 instead of 403 with Spring Boot 2

Heads up

By default Spring Boot 2 will return 401 when spring-boot-starter-security is added as a dependency and an unauthorized request is performed.

This may change if you place some custom configurations to modify the security mechanism behavior. If that’s the case and you truly need to force the 401 status, then read the below original post.

Original Post

The class org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint was removed in favor of org.springframework.security.web.authentication.HttpStatusEntryPoint.

In my case the code would go like this:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
        //...
    }
}

Bonus

If you need to return some information in the response body or customize the response somehow you can do something like this:

1- Extend AuthenticationEntryPoint

public class MyEntryPoint implements AuthenticationEntryPoint {
    private final HttpStatus httpStatus;
    private final Object responseBody;

    public MyEntryPoint(HttpStatus httpStatus, Object responseBody) {
        Assert.notNull(httpStatus, "httpStatus cannot be null");
        Assert.notNull(responseBody, "responseBody cannot be null");
        this.httpStatus = httpStatus;
        this.responseBody = responseBody;
    }

    @Override
    public final void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.setStatus(httpStatus.value());

        try (PrintWriter writer = response.getWriter()) {
            writer.print(new ObjectMapper().writeValueAsString(responseBody));
        }
    }
}

2- Provide an instance of MyEntryPoint to the security configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // customize your response body as needed
        Map<String, String> responseBody = new HashMap<>();
        responseBody.put("error", "unauthorized");

        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new MyEntryPoint(HttpStatus.UNAUTHORIZED, responseBody));
        //...
    }
}

Leave a Comment