With Spring Boot 1.5.6.RELEASE I was able to send HTTP Status code 401
instead of 403
as described in How let spring security response unauthorized(http 401 code) if requesting uri without authentication, by doing this:
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //... http.exceptionHandling() .authenticationEntryPoint(new Http401AuthenticationEntryPoint("myHeader")); //... } }
using the org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
class.
I just upgraded to Spring Boot 2.0.0.RELEASE and found there is not such class any more (at least in that package).
Questions:
Does this class (
Http401AuthenticationEntryPoint
) exist yet in Spring Boot?If no, what could be a good alternative for keeping the same behavior in an existing project in order to keep consistency with other implementations which depend on this status code (
401
) instead of403
?
Please notice this is different from Spring Security anonymous 401 instead of 403 because it’s referring specifically to SpringBoot 2 (there are solutions in that post not applicable anymore in SpringBoot version 2 or others are not needed at all)
Advertisement
Answer
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)); //... } }