Spring Security系列教程之解决Spring Security环境中的跨域问题

这篇具有很好参考价值的文章主要介绍了Spring Security系列教程之解决Spring Security环境中的跨域问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 启用Spring Security 的CORS支持

1. 普通的跨域
方式1:在接口方法上利用@CrossOrigin注解解决跨域问题
@RestController
public class IndexController {

    @CrossOrigin(value = "http://localhost:8082")
    @GetMapping("/hello")
    public String hello() {

        return "get hello";
    }

    @CrossOrigin(value = "http://localhost:8082")
    @PostMapping("/hello")
    public String hello2() {

        return "post hello";
    }
}
方式2:通过实现WebMvcConfigurer接口来解决跨域问题
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8082")
                .allowedMethods("*")
                .allowedHeaders("*");
    }

}

二. Spring Security环境下的跨域问题解决

通过上面的配置,我们已经解决了Ajax的跨域请求问题,但是这个案例中也有潜在的威胁存在,常见的就是 CSRF(Cross-site request forgery) 跨站请求伪造。跨站请求伪造也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。

所以为了提高网站的安全性,我在上面Spring Boot项目的基础之上,添加Spring Security的依赖包,但是暂时不进行任何别的操作。

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

Spring Security系列教程之解决Spring Security环境中的跨域问题

2. 解决Spring Security环境下跨域问题的4种方案

通过实验可知,如果使用了 Spring Security,上面的跨域配置会失效,因为请求会被 Spring Security 拦截。那么在Spring Security环境中,如何解决跨域问题呢?这里我们有3种方式可以开启 Spring Security 对跨域的支持。

2.1 方式一:开启cors方法

我们在上面的案例之上,编写一个SecurityConfig配置类,在configure方法中,利用cors() 开启Spring Security 对 CORS 的支持:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

 @Override
 protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests()
             .anyRequest()
             .permitAll()
             .and()
             .formLogin()
             .permitAll()
             .and()
             .httpBasic()
             .and()
             //支持跨域访问
             .cors()
             .and()
             .csrf()
             .disable();
 }

}
2.2 方式二:进行全局配置

第二种方式是去除上面的跨域配置,直接在 Spring Security 中做全局配置,如下:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .permitAll()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .httpBasic()
                .and()
                //支持跨域访问
                .cors()
                .configurationSource(corsConfigurationSource())
                .and()
                .csrf()
                .disable();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.setAllowedOrigins(Collections.singletonList("*"));
        configuration.setAllowedMethods(Collections.singletonList("*"));
        configuration.setAllowedHeaders(Collections.singletonList("*"));
        configuration.setMaxAge(Duration.ofHours(1));
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}

以上2个方法,都可以实现在Spring Security环境下的跨域访问。

2.3 方式三:支持OAuth2的跨域访问

我们开发时,还有一种情况就是支持 OAuth2 相关接口的跨域,比如用户要访问 OAuth2 中的 /oauth/token 等接口。我们可以配置一个全局的 CorsFilter 跨域过滤器类,核心代码如下:文章来源地址https://www.toymoban.com/news/detail-454877.html

/**
* 跨域配置方式3:定义全局跨域过滤器
**/
@Configuration
public class GlobalCorsConfiguration {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
    
}

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //跨域方式3:
        http.requestMatchers()
                .antMatchers(HttpMethod.OPTIONS, "/oauth/**")
                .and()
                .csrf()
                .disable()
                .formLogin()
                .and()
                .cors();
    }
}
2.4 方式4 :自定义一个全局跨域处理Filter
public class CorsFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        String orignalHeader = StringUtils.defaultIfBlank(request.getHeader("Origin"), "*");
        // 指定本次预检请求的有效期
        response.setHeader("Access-Control-Max-Age", "3600");
        // 服务器支持的所有头信息字段
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        response.setHeader("Access-Control-Allow-Origin", orignalHeader);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        filterChain.doFilter(request, response);
    }
}

public class WebMvcConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new CorsFilter (), WebAsyncManagerIntegrationFilter.class);
    }
}

到了这里,关于Spring Security系列教程之解决Spring Security环境中的跨域问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring security 解决跨域】

    主页传送门:📀 传送   Spring Security是一个功能强大且高度可定制的,主要负责为Java程序提供声明式的身份验证和访问控制的安全框架。其前身是Acegi Security,后来被收纳为Spring的一个子项目,并更名为了Spring Security。Spring Security的底层主要是基于Spring AOP和Servlet过滤器来实

    2024年02月13日
    浏览(22)
  • Spring Security——09,解决跨域

    浏览器出于安全的考虑,使用 XMLHttpRequest对象发起 HTTP请求时必须遵守同源策略,否则就是跨 域的HTTP请求,默认情况下是被禁止的。 同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。 前后端分离项目,前端项目和后端项目一般都不是同源的,所以

    2024年04月15日
    浏览(9)
  • 系列二、Spring Security中的核心类

    1.2.1、概述         Spring Security 提供了多种密码加密方案,官方推荐使用 BCryptPasswordEncoder,BCryptPasswordEncoder 使用 BCrypt 强哈希函数,开发者在使用时可以选择提供 strength 和 SecureRandom 实例。strength 越大,密钥的迭代次数越多,密钥迭代次数为 2^strength。strength 取值在 4~3

    2024年02月01日
    浏览(18)
  • 系列六、Spring Security中的认证 & 授权 & 角色继承

            关于Spring Security中的授权,请参考【系列一、认证 授权】,这里不再赘述。 1.4.1、admin登录 (一) 登录 (二) 访问sayHi(登录就可以访问) (三)访问/admin/helloWorld接口(需要拥有admin角色)  (四)访问/dba/helloWorld接口(需要拥有dba角色,admin自动继承dba角色)

    2024年02月01日
    浏览(16)
  • 解决vite的跨域问题

    vue需要配置自定义代理规则进行跨域访问 官方文档:https://cn.vitejs.dev/config/server-options.html#server-proxy 在vite.config.ts修改: 发起请求的地方: 生产环境配置跨域,还需要编辑nginx的配置文件,在 server 对象中再添加一个 location 对象(别忘了上一个对象末尾的分号 ; )

    2024年02月04日
    浏览(18)
  • 常见的跨域解决方案

    常见的跨域解决方案: 跨域问题可以分为两种情况: 前端跨域和后端跨域 。以下是针对这两种情况的跨域解决方案: 前端跨域解决方案: JSONP: 适用于前端向不同域名下的服务器请求数据,通过添加回调函数名称来实现跨域数据获取。 CORS: 当前端向服务器请求数据时,

    2024年02月12日
    浏览(19)
  • 跨域问题?无需担心!学习如何解决 Axios 的跨域限制

    跨域是指访问另外一个域的资源,由于浏览器的同源策略,默认情况下使用 XMLHttpRequest 和 Fetch 请求时是不允许跨域的。跨域的根本原因是浏览器的同源策略,这是由浏览器对 JavaScript 施加的安全限制。 跨域请求被阻止 (Cross-Origin Request Blocked) : 这是由浏览器实施的同源策略

    2024年04月27日
    浏览(19)
  • 系列四、Spring Security中的认证 & 授权(前后端不分离)

    1.3.1、概述         前后端不分离的登录成功回调有两个关键方法,即:defaultSuccessUrl 和 successForwardUrl。那么它们之间的区别是什么呢?        (1)successForwardUrl 表示不管你是从哪里来的,登录后一律跳转到 successForwardUrl 指定的地址。例如 successForwardUrl 指定的地址为/l

    2024年01月19日
    浏览(20)
  • 跨域介绍及Java中常见的跨域解决方案

    跨域(Cross-Origin)指的是在浏览器中,由于安全策略的限制,当前网页的 JavaScript 代码无法直接访问不同源(协议、域名、端口)的资源。这意味着如果网页尝试通过 AJAX、Fetch 或 WebSocket 等方式向不同源的服务器发送请求,浏览器会阻止这些请求,从而避免潜在的安全风险。

    2024年02月07日
    浏览(18)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包