Springboot2.6以下版本对cookie的samesite设置的通用方法

解决Spring应用中SameSiteCookie漏洞的策略
本文介绍了在Spring技术栈应用中检测到的CookiewithoutSameSiteattribute漏洞,详细讲述了如何通过Nginx/Apache设置、SpringBoot配置以及自定义HeaderWriter来解决这个问题。

      通过安全扫描工具对spring技术栈开发的应用进行漏洞检查时,通常会扫描出关于cookie相关的漏洞,其中一个是: Cookie without SameSite attribute,对于其描述通常如下: 

When cookies lack the SameSite attribute, Web browsers may apply different and

sometimes unexpected defaults. It is therefore recommended to add a SameSite
attribute with an appropriate value of either "Strict", "Lax", or "None".
       由于Java Servlet 3.x/4.0 规范不支持 SameSite cookie 属性,所以要解决此类问题没有一个统一的方式。如何解决此问题呢? 大家在网上找到的解决方案有三类:
1.  Nginx或APACHE SERVER这些代理服务器上设置:
    以nginx为例:proxy_cookie_path / "/; httponly; secure; SameSite=Lax";
2.  在添加完cookie时,加下如下代码:
   
 Cookie cookie = new Cookie("test_001", UriUtils.encode("123457890", "UTF-8"));
      cookie.setPath("/");
      cookie.setMaxAge(-1);
      cookie.setHttpOnly(true);
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
    boolean firstHeader = true;
    for (String header : headers) { // there can be multiple Set-Cookie attributes
      if (firstHeader) {
        response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; SameSite=%s", header, this.cookieSameSite));
        firstHeader = false;
        continue;
      }
      response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; SameSite=%s", header, this.cookieSameSite));
    }

3. 对于springboot2.6及以上版本,设置:server.session.cookie.same-site=LAX

但对于springboot2.6以下版本来说,利用spring security本身的机制解决此问题没有统一的方式。考虑到spring在写http header时利用了org.springframework.security.web.header.HeaderWriter,所以可以通过自定义一个SameSiteCookieHeaderWriter来实现。具体实现如下:

  a) 实现一个自定义HeaderWriter: SameSiteCookieHeaderWriter

    

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpHeaders;
import org.springframework.security.web.header.HeaderWriter;

/**
 * 安全问题: Cookie without SameSite attribute
 * 
 */
public class SameSiteCookieHeaderWriter implements HeaderWriter {

  private String cookieSameSite;

  public SameSiteCookieHeaderWriter(String cookieSameSite) {
    this.cookieSameSite = cookieSameSite;
    if (this.cookieSameSite.equalsIgnoreCase("NONE") || this.cookieSameSite.equalsIgnoreCase("LAX")
      || this.cookieSameSite.equalsIgnoreCase("STRICT")) {
      this.cookieSameSite = "LAX";
    } else {
      this.cookieSameSite = this.cookieSameSite.toUpperCase();
    }

  }

  /*  
   *(non-Javadoc)  
   * @see org.springframework.security.web.header.HeaderWriter#writeHeaders(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)  
   */
  @Override
  public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {

    Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
    boolean firstHeader = true;
    for (String header : headers) { // there can be multiple Set-Cookie attributes
      if (firstHeader) {
        response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; SameSite=%s", header, this.cookieSameSite));
        firstHeader = false;
        continue;
      }
      response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; SameSite=%s", header, this.cookieSameSite));
    }

  }

}

b) 在WebSecurityConfigurerAdapter的configure(HttpSecurity http) 中加上此SameSiteHeaderWriter

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http. //
      cors().and(). //
      csrf().disable().//
      sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    // 设置 X-Frame-Options
    // disable 是没有 X-Frame-Options
    // 没有 disable 就是 DENY
    // sameOrigin 就是 SAMEORIGIN
    http.headers().frameOptions().sameOrigin(); // disable submit dc99635
     // http.headers().frameOptions().disable(); // 按配置来
     

    http.headers().xssProtection().xssProtectionEnabled(true).block(true);
    
    http.headers().addHeaderWriter(new SameSiteCookieHeaderWriter("LAX"));
 
  }
  
}

这种方法相对来说比较优雅,其原理是利用springsecurity的HeaderWriter机制将原来的Set-Cookie重写了。

<think>好的,我现在要解决用户的问题:查找Spring Boot 2.6与Elasticsearch的兼容版本。首先,我需要确定用户的需求是什么。用户可能正在开发一个使用Spring Boot 2.6的项目,需要集成Elasticsearch,但不确定该用哪个版本的Elasticsearch才能兼容。他们可能遇到了版本冲突或者配置问题,所以需要明确的版本对应关系。 接下来,我应该回忆一下Spring Boot官方文档中关于依赖管理的部分。Spring Boot通常会在其文档中列出所管理的依赖及其兼容版本。对于Elasticsearch,Spring Boot通过spring-boot-starter-data-elasticsearch来集成,而底层可能依赖Elasticsearch的客户端库,比如Transport Client或者High Level REST Client,不过现在Elasticsearch的Java API可能有变化,特别是从7.x之后推荐使用新的Java客户端。 我记得Spring Boot每个版本都会指定其依赖的第三方库的版本,这些信息可以在Spring Boot的官方文档的“Dependency Versions”附录中找到。例如,Spring Boot 2.6.x对应的Elasticsearch客户端版本可能是在7.x系列,但具体的小版本需要确认。 另外,需要注意Elasticsearch本身的版本和客户端库的版本之间是否需要严格匹配。例如,Elasticsearch服务器版本和High Level REST Client的版本通常需要保持一致,否则可能会出现兼容性问题。不过,Spring Boot可能通过依赖管理来简化这一点,自动引入兼容的客户端版本。 现在,我需要验证这些信息。查阅Spring Boot 2.6的官方文档,在附录中找到依赖版本列表。假设在Spring Boot 2.6.4中,Elasticsearch的客户端版本是7.16.2,那么对应的Elasticsearch服务器版本也应该是7.16.2。但可能有些版本会有一定的兼容范围,比如客户端版本7.16.x可能兼容Elasticsearch服务器7.16.x到7.x的某个范围,但最好保持严格一致以避免问题。 此外,用户可能需要知道如何配置Elasticsearch的连接信息,比如在application.properties中设置spring.elasticsearch.rest.uris等属性。如果用户使用的是Spring Data Elasticsearch,还需要注意Spring Data的版本与Elasticsearch客户端的兼容性,因为Spring Data Elasticsearch可能会有自己的版本要求。 如果用户遇到兼容性问题,可能需要检查依赖树,确保没有其他库引入了不同版本的Elasticsearch客户端。可以使用Maven的mvn dependency:tree或Gradle的依赖分析工具来排查冲突。 总结步骤: 1. 确定Spring Boot 2.6使用的Elasticsearch客户端版本2. 根据客户端版本确定对应的Elasticsearch服务器版本。 3. 提供配置示例和常见问题解决方法。 可能遇到的问题: - 用户使用的Elasticsearch版本过高或过低,导致不兼容。 - 依赖冲突导致客户端版本不正确。 - 配置参数设置错误,无法连接到Elasticsearch。 需要确保引用的信息准确,参考官方文档或可靠的来源,比如Spring Boot的GitHub仓库或官方发布说明。如果有多个来源提到不同的版本,需要确认哪个是正确的,或者指出可能的版本范围及建议。</think>Spring Boot 2.6.x 官方支持的 Elasticsearch 客户端版本为 **7.16.2**,对应的 Elasticsearch 服务器版本建议使用 **7.16.x** 系列[^1]。以下是具体分析和配置方法: --- ### 一、版本对应关系 1. **Spring Boot 2.6.x 依赖的 Elasticsearch 客户端版本** 通过 `spring-boot-dependencies-2.6.x.pom` 文件可查,Spring Boot 2.6.x 默认管理的 Elasticsearch REST Client 版本为: $$ \text{Elasticsearch Client} = 7.16.2 $$ 此版本对应 Elasticsearch 服务器 **7.16.2**,建议严格匹配以避免兼容性问题[^1]。 2. **Spring Data Elasticsearch 兼容性** Spring Boot 2.6.x 集成的 Spring Data Elasticsearch 版本为 `4.3.x`,该版本仅支持 Elasticsearch 7.x 系列,且推荐使用 REST Client 而非过时的 Transport Client[^2]。 --- ### 二、配置示例 在 `pom.xml` 中无需显式声明 Elasticsearch 版本(Spring Boot 已自动管理): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 在 `application.properties` 中配置 Elasticsearch 服务器地址: ```properties spring.elasticsearch.rest.uris=http://localhost:9200 ``` --- ### 三、常见问题排查 1. **版本不匹配错误** 若出现 `NoNodeAvailableException` 或 `MapperParsingException`,通常是客户端与服务器版本不一致导致。解决步骤: - 检查 Elasticsearch 服务器版本:`curl http://localhost:9200` - 确保客户端版本与服务器版本一致。 2. **依赖冲突** 使用 Maven 检查依赖树: ```bash mvn dependency:tree -Dincludes=org.elasticsearch ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值