When I type into browser any route of my React app, for example: http://localhost/login, the request hits my server, and my server responds with 401 Unauthorized.
When request is not an authorized backend api I’d like to handle the request in my react routing.
WebSecurityConfig.java:
@Override protected void configure(HttpSecurity http) throws Exception { http ... .formLogin() .disable() .authorizeRequests() .antMatchers( "/error", "/", "/favicon.ico", "/static/**", "/api/auth/**", "/api/oauth2/**", "/api/courses/**", "/api/stripe/**", "/api/lesson/content") .permitAll() .anyRequest() .authenticated() .and() ... .exceptionHandling() .authenticationEntryPoint(new RestAuthenticationEntryPoint()) .and(); http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); }
RestAuthenticationEntryPoint.java:
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getLocalizedMessage()); } }
Is there a way to forward the request to index.html in RestAuthenticationEntryPoint?
Advertisement
Answer
I’ve decided to throw 404 Not Found exception from RestAuthenticationEntryPoint, because I think it matches this use case more than 401 Unathorized:
@Override public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.getLocalizedMessage()); }
And redirect not found exception to the front end:
@Bean public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() { return container -> { container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound")); }; }
@Controller public class CustomErrorController { @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/notFound") public String error() { return "forward:/index.html"; } }
The disadvantage of this approach is that I can’t throw 404 from any controller, because it won’t be returned to the frontend, but I can live with it.