统一认证,跨域cookie写入问题,修改sameSite。

场景:认证中心采用iframe嵌套业务平台的模式,进行oauth2.授权,跨域cookie写入问题。

在做oauth2.0授权的时候,第三方平台需要用到cookie进行内部鉴权,这个时候不同域的情况下,会导致cookie无法写入。主要解决方式是修改cookie的sameSite属性。
这里的sameSite属性其实是限制cookie的,有三种策略,严格模式-strict,宽松模式-lax,以及none。而我们目前要用到的就是none的模式,在这种模式下,必须同时启用Secure才行。
1. javax.servlet.http包下面的cookie是无法修改sameSite属性的,需要先引入下面这个依赖
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>3.1.0</version>
        </dependency>
2. 需要考虑到浏览器兼容问题,360或者搜狗有些低版本不支持修改,但他们本身是不需要修改sameSite就可以正常写入cookie的,而谷歌或者edge则需要修改sameSite。下面做一个兼容处理。
    /**
     * 判断是否支持SameSite=None
     *
     * @param request
     * @return true(不支持), false(支持)
     */
    public static Boolean disallowsSameSiteNone(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        if (StringUtils.isEmpty(userAgent)) {
            return false;
        }

        // Cover all iOS based browsers here. This includes:
        // - Safari on iOS 12 for iPhone, iPod Touch, iPad
        // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
        // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
        // All of which are broken by SameSite=None, because they use the iOS networking
        // stack.
        if (userAgent.contains("CPU iPhone OS 12") || userAgent.contains("iPad; CPU OS 12")) {
            return true;
        }

        // Cover Mac OS X based browsers that use the Mac OS networking stack.
        // This includes:
        // - Safari on Mac OS X.
        // This does not include:
        // - Chrome on Mac OS X
        // Because they do not use the Mac OS networking stack.
        if (userAgent.contains("Macintosh; Intel Mac OS X 10_14") &&
                userAgent.contains("Version/") && userAgent.contains("Safari")) {
            return true;
        }

        // Cover Chrome 50-69, because some versions are broken by SameSite=None,
        // and none in this range require it.
        // Note: this covers some pre-Chromium Edge versions,
        // but pre-Chromium Edge does not require SameSite=None.
        if (userAgent.contains("Chrome/5") || userAgent.contains("Chrome/6")) {
            return true;
        }

        return false;
    }
3.利用DefaultCookieSerializer对cookie进行特殊处理,这里需要注意useSecureCookie需要设置为true;其次是serializer默认useBase64Encoding = true,会将你设置的cookie值自动进行编码,这里根据你的实际情况进行处理。
    public static void authCookie(HttpServletRequest request, HttpServletResponse response,
                                  String name, String value, Long expires) {

        // 判断浏览器是否支持SameSite=None
        Boolean flag = disallowsSameSiteNone(request);
        if (flag) {
            // 不支持
            Cookie cookie = new Cookie(name, value);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            cookie.setMaxAge(Math.toIntExact(expires));
            response.addCookie(cookie);
            return;
        }
        // 支持
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName(name);
        serializer.setCookieMaxAge(Math.toIntExact(expires));
        serializer.setCookiePath("/");
        serializer.setSameSite("NONE");
        serializer.setUseSecureCookie(true);
        serializer.setUseBase64Encoding(false);

        // 写入cookie
        CookieSerializer.CookieValue cookieValue = new CookieSerializer.CookieValue(request, response, value);
        serializer.writeCookieValue(cookieValue);

    }
serializer具体的实现细节可以查阅源码writeCookieValue方法。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值