Spring Security拦截器引起Java CORS跨域失败的问题及解决

Spring Security拦截器引起Java CORS跨域失败的问题及解决

在使用Spring Security进行接口保护的时候,经常会遇到因为跨域问题导致前端无法访问服务器接口的问题。本文将详细介绍Spring Security拦截器引起Java CORS跨域失败的问题及解决。

什么是CORS跨域

CORS(Cross-Origin Resource Sharing)即跨域资源共享,是一种用于跨域访问资源的机制。当一个域的JavaScript代码向另外一个域发送请求时,就会触发跨域。由于JavaScript的同源策略限制,这时的请求会被终止。

Spring Security拦截器引起Java CORS跨域失败的问题

Spring Security使用拦截器来保护接口,如果没有正确配置,就会导致跨域请求失败。具体表现为前端向服务器发送请求时,收到错误提示:

Access to XMLHttpRequest at 'http://example.com/api/someapi' from origin 'http://localhost:8080' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested 
resource.

这是因为服务器拦截器不允许来自不同域的请求。具体来说,是因为在服务器端请求头缺少Access-Control-Allow-Origin字段。如果在前端代码中添加这个字段,就可以通过CORS跨域访问接口。但是由于拦截器的存在,这并不是一个解决办法。

解决Spring Security拦截器引起Java CORS跨域失败的问题

要解决Spring Security拦截器引起Java CORS跨域失败的问题,可以采用以下步骤。

步骤1:添加Filter

在Server端添加一个过滤器,如下所示:

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers",
                "Authorization, Content-Type, Accept, X-Requested-With, Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
        response.setHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin,Access-Control-Allow-Credentials");

        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig config) throws ServletException {}
}

这个过滤器会在请求进入拦截器前执行,并添加CORS信息。

步骤2:配置Spring Security

在SecurityConfig类中添加以下代码:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/api/**").permitAll()
            .anyRequest().authenticated()
            .and().csrf().disable();
    http.addFilterBefore(corsFilter, ChannelProcessingFilter.class);
}

这里的api/**是需要允许跨域访问的接口路径,.antMatchers("/api/**").permitAll()的意思是对这些接口不进行权限验证。

这样就可以解决Spring Security拦截器引起Java CORS跨域失败的问题了。

示例1:允许所有的请求跨域

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin,Access-Control-Allow-Credentials");

        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig config) throws ServletException {}
}

以上代码的作用是允许所有的请求跨域,通常不建议使用,因为这会导致服务器存在安全风险。

示例2:只允许指定域名的请求跨域

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        String origin = request.getHeader("Origin");
        if (origin != null && (origin.contains("example.com") || origin.contains("example.cn"))) {
            response.setHeader("Access-Control-Allow-Origin", origin);
        }

        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin,Access-Control-Allow-Credentials");

        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig config) throws ServletException {}
}

以上代码的作用是只允许来自example.comexample.cn的域名请求跨域。如果请求的域名不在白名单中,服务器会拒绝该请求。这样做可以有效地防止跨站点伪造请求(CSRF)。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security拦截器引起Java CORS跨域失败的问题及解决 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Spring SpringMVC在启动完成后执行方法源码解析

    在Spring和SpringMVC中,我们可以在启动完成后执行一些方法。本文将详细讲解Spring和SpringMVC在启动完成后执行方法的源码解析,并提供两个示例说明。 Spring中启动完成后执行方法 在Spring中,我们可以使用ApplicationListener接口来监听ApplicationContext的启动事件。下面是一个示例: @Comp…

    Java 2023年5月18日
    00
  • java 异常被catch后 将会继续执行的操作

    Java 异常被 catch 后,程序会执行 catch 块中的代码,而不是直接终止程序的执行。在处理完异常后,程序可以选择恢复正常状态并继续执行,或者让异常传递到更高级别的异常处理程序进行处理。 下面是 Java 异常被 catch 后将会继续执行的操作的完整攻略: 恢复程序正常状态 当程序发生异常时,可以在 catch 块中编写代码来恢复程序的正常状态。…

    Java 2023年5月27日
    00
  • Java 使用IO流实现大文件的分割与合并实例详解

    Java 使用IO流实现大文件的分割与合并实例详解 前言 在现代应用程序中,经常需要处理非常大的文件。处理大文件的一种常见方法是将它们分成更小的文件,这有助于减少I/O操作的时间和资源消耗。在Java中,可以使用IO流来实现大文件的分割与合并。 分割文件 读取源文件 首先,我们需要通过使用Java IO API中的FileInputStream读取要分割的源…

    Java 2023年5月20日
    00
  • 多模块maven的deploy集成gitlab ci自动发版配置

    针对“多模块maven的deploy集成gitlab ci自动发版配置”这一问题,我将给出如下详细攻略: 一、需求分析 首先,我们需要对我们的需求进行分析。通常,在项目开发过程中,我们采用Maven进行项目管理和构建,而且在多模块项目中,通常会使用Maven的deploy插件进行自动化部署。同时,为了提高开发效率,我们需要集成CI/CD工具,以实现代码提交后…

    Java 2023年5月19日
    00
  • 基于Java中的StringTokenizer类详解(推荐)

    下面是关于“基于Java中的StringTokenizer类详解”的完整攻略。 1. 什么是StringTokenizer类? StringTokenizer类是Java中用来分割字符串的类,它的作用类似于split()方法。使用StringTokenizer类可以将一个字符串按照指定的分隔符进行分割,得到一个包含多个子字符串的字符串数组。 2. Strin…

    Java 2023年5月27日
    00
  • Spring 零基础入门WebFlux框架体系

    Spring 零基础入门WebFlux框架体系攻略 什么是WebFlux Spring WebFlux是Spring框架的一个子项目,它提供了一种处理响应式HTTP请求的方式,支持反应式流和异步编程模型。使用WebFlux,我们可以编写非阻塞的、响应式的应用程序,可以处理大量的并发请求而不会像传统的Servlet容器一样阻塞线程。 如何使用WebFlux 首…

    Java 2023年5月19日
    00
  • Window搭建部署RocketMQ步骤详解

    下面是详细讲解“Window搭建部署RocketMQ步骤详解”的完整攻略。 Window搭建部署RocketMQ步骤详解 RocketMQ是一个分布式消息传递系统,由阿里巴巴团队开发和维护。在实际开发中,我们经常需要使用消息队列来进行异步通信与解耦。本文将介绍如何在Window平台上搭建和部署RocketMQ。 步骤一:下载和安装JDK RocketMQ是基…

    Java 2023年5月20日
    00
  • win2003 服务器 安全设置 技术实例(比较安全的方法)

    Win2003服务器安全设置技术实例 作为一名运维人员,服务器安全设置是不可或缺的一项工作。下面介绍一些比较安全的 Win2003 服务器的技术实例。 禁用不必要的服务 Win2003 服务器中默认启动多项服务,而其中有些服务并不是所有人都需要的。禁用这些不必要的服务,可以减少服务器的攻击面。在启用服务之前,务必确认该服务是否对服务器的正常运行有必要。 下面…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部