与Servlet过滤器和FilterRegistrationBean一起使用时,跨源资源共享不起作用

时间:2018-04-10 09:15:03

标签: java spring spring-boot cors cross-domain

摘要:对于跨源请求,正在发送具有有效JSON的响应。 (即不发送空响应。)

我有一个filterRegistrationBean,如下所示:

@Bean
public FilterRegistrationBean corsFilterRegistration() {
    FilterRegistrationBean filterRegistrationBean =
            new FilterRegistrationBean(corsFilter());
    filterRegistrationBean.setUrlPatterns(Collections.singleton("/getToken"));
    return filterRegistrationBean;
}

@Bean
public CORSFilter corsFilter() {
    return new CORSFilter();
}

我有一个CORSFilter类,如下所示:

@Component
public class CORSFilter implements Filter {
    @Autowired
    UserDao userDao;

    @Autowired
    UserController userController;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest requestToUse = (HttpServletRequest) request;
        HttpServletResponse responseToUse = (HttpServletResponse) response;
        String origin = requestToUse.getHeader("Origin");
        String username = requestToUse.getParameter("username");


        if (requestToUse.getMethod().equalsIgnoreCase("GET") && Util.falseIfAnyStringIsNull(username, origin)) {
            User user = userDao.findByUsername(username);
            if (!ObjectUtils.isEmpty(user)) {
                System.out.println("user.getDomainName()==" + user.getDomainName());
                if (origin.equalsIgnoreCase(user.getDomainName())) {
                    logger.info("Access granted");
                    responseToUse.addHeader("Access-Control-Allow-Origin", origin);
                    responseToUse.addHeader("Access-Control-Allow-Methods", "GET");
                    responseToUse.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                    chain.doFilter(requestToUse, responseToUse);
                } else {
                    responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Origin.");
                }

            } else {
                responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Username");
            }

        } else {
            responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Credential");
        }
    }


    @Override
    public void destroy() {

    }
}

如果对/ getToken发出请求,则CORSFilter开始运行并验证用户和来源。

这一切都很好,但问题是当我从无效的来源发送一个get请求到/ getToken然后在浏览器控制台中,我得到一个正确的消息," No' Access-控制允许来源'标头出现在请求的资源上...... " 但如果我进入网络选项卡,那么我可以看到一个JSON响应,其中包含有效的令牌。

如果我删除上面的CORSFilter和filterRegistrationBean,那么我没有看到任何响应,所以我假设上面的过滤器和registrationBean有问题。

1 个答案:

答案 0 :(得分:2)

Spring Framework正在为此目的提供org.springframework.web.filter.CorsFilter实现和各种功能,例如@CrossOrigin。(请参阅the reference documentation)。

滚动自己的过滤器实现不是一个好主意;在我的头脑中,你的实现不处理预检请求,这可能是你现在面临的(一个)问题。