tomcat中使用SessionCookieConfig接口使httpOnly值生效

描述:SessionCookieConfig用来修改会话跟踪的cookie的相关信息,包含name,path,domain,以前名称是固定的必须为JSESSIONID,但是通过该接口可以实现自定义。

 

背景:

  Springboot 2.0 (spring-session-data-redis + spring-boot-starter-web)

 

需求: 

  通过cookies中取到的 sessionid 获取到 session

 

预期效果:

  @Autowired

  private SessionRepositry sessionRepositry;

  ...

  Session session = sessionRespositry.findById(sessionId);

 

真实结果: 获取到的session是null, 然而通过 request.getSession(); 可以获取到session, 说明 session是存在的.

 

问题追踪后发现问题:

  cookie中的sessionId 与 session.getId() 不一样!!!

 

DEBUG:

  1. 先看一看SpringSession是如何从Cookie中获取sessionid的! (相关类: org.springframework.session.web.http.DefaultCookieSerializer)

   

  2. 再看一看 useBase64Encoding 的值是啥, 首先看默认值

 

   3. 看看这些配置是在哪里被(赋值)确认的, 一路追踪到 org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration 配置类中

 

 看看 createDefaultCookieSerializer() 是如何实现的

 

  4. 从上面可以得出结论, 我们无法 通过配置文件 中 server.servlet.session.** 来配置 useBase64Encoding. 使 cookie中的 sessionid 与 session.getId() 保持一致

  

  5. 期间发现的另一个问题: 虽然 sessionCookieConfig 有httpOnly相关配置, 但这里并未将配置设入 cookieSerializer 中, 导致配置文件中的 server.servlet.session.cookie.httpOnly = false 不起作用

  

解决方案:

  第一种方案:  通过配置 自定义的 CookieSerializer 来指定配置信息(如果觉得麻烦请直接看第二种方案), 如下

  a) 首先因为 SessionCookieConfig 接口中并没有定义 isUseBase64Encoding() 等接口, 导致缺少了部分配置, 所以我 自定义了一个 MySessionCookieConfig 接口继承了 SessionCookieConfig, 并写了一个默认实现 MyDefaultSessionCookieConfig

 MySessionCookieConfig
 MyDefaultSessionCookieConfig

  b) 利用 MyDefaultSessionCookieConfig 携带的配置, 自定义 CookieSerializer Bean

 RedisSessionConfig

  c) 修改配置文件配置

  

  d) 配置完成后重新启动, 再看 SpringHttpSessionConfiguration 加载的时候, 拿到了我们自定义的 CookieSerializer, 我想要的配置都有了!! 打开浏览器测试通过!!

 

   第二种方案: 拿到 Cookie 中的 sessionId 后, 手动解码, 再 通过 sessionRespositry.findById(sessionId); 获取session

    a) 解码的方案 从 DefaultSerializer 类中 copy 一个 , 如下:

复制代码
复制代码
    /**
     * Decode the value using Base64.
     * @param base64Value the Base64 String to decode
     * @return the Base64 decoded value
     * @since 1.2.2
     */
    private String base64Decode(String base64Value) {
        try {
            byte[] decodedCookieBytes = Base64.getDecoder().decode(base64Value);
            return new String(decodedCookieBytes);
        }
        catch (Exception e) {
            return null;
        }
    }
复制代码
复制代码

    b) 获取步骤:

      String cookieSessionId = "XXX";

      String sessionId = base64Decode(cookieSessionId);

      Session session = sessionRespositry.findById(sessionId);

    c) 搞定! (此方案未解决 httpOnly 不起效的问题, 如果要解决 httpOnly = false , 请看方案一)

 

转自:https://www.cnblogs.com/imyjy/p/9187168.html

posted @   ppjj  阅读(1409)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2017-06-06 MySQL存储引擎--MyISAM与InnoDB区别
点击右上角即可分享
微信分享提示