spring安全:在401情况下重定向到单页应用程序

jrcvhitl  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(316)

当我在浏览器中键入react应用程序的任何路由时,例如:http://localhost/login,请求将命中我的服务器,而我的服务器将以401 unauthorized响应。
当请求不是授权的后端api时,我希望在react路由中处理请求。
WebSecurity配置.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);
}

重新验证入口点.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());
    }
}

是否有方法将请求转发到restauthenticationentrypoint中的index.html?

dwthyt8l

dwthyt8l1#

你只需要处理一个 401 在react内:

axios.post('http://localhost:8080/login', data)
    .then(resp => ...)
    .catch(e => {
        if (e.response && e.response.status===401) 
            history.push('/error');
    });

或者你可以修改你的 AuthenticationHandler :

@Override
    public void commence(HttpServletRequest httpServletRequest,
                         HttpServletResponse httpServletResponse,
                         AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendRedirect("http://localhost:3000/error");
    }
fcipmucu

fcipmucu2#

我决定从restauthenticationentrypoint抛出404 not found exception,因为我认为它比401 unthorized更符合这个用例:

@Override
    public void commence(HttpServletRequest httpServletRequest,
                         HttpServletResponse httpServletResponse,
                         AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND,
                e.getLocalizedMessage());
    }

并将未发现异常重定向到前端:

@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";
    }

}

这种方法的缺点是我不能从任何控制器抛出404,因为它不会返回到前端,但我可以接受它。

相关问题