Springboot+Shiro出现SameSite问题

首先说明一下低版本的shiro-spring是没有这个问题的,发现这个问题的shiro-spring是1.5.2版本

没有去考证过到哪个版本会出现这个问题,但是肯定的是新版本shiro-spring对cookie加上了SameSite属性

然后网上说的配置CookieSerializer方式是不会起作用的,原因是当引入shiro-spring之后,对于cookie的序列化操作会托管给shiroweb,而CookieSerializer是springweb中的序列化cookie的类,所以再怎么配置CookieSerializer都不会起作用,应当从shiro配置的角度出发去解决这个问题

在debug的时候发现最后cookie转成header时调用了SimpleCookie中的saveTo方法

    public void saveTo(HttpServletRequest request, HttpServletResponse response) {

        String name = getName();
        String value = getValue();
        String comment = getComment();
        String domain = getDomain();
        String path = calculatePath(request);
        int maxAge = getMaxAge();
        int version = getVersion();
        boolean secure = isSecure();
        boolean httpOnly = isHttpOnly();
        SameSiteOptions sameSite = getSameSite();

        addCookieHeader(response, name, value, comment, domain, path, maxAge, version, secure, httpOnly, sameSite);
    }

可以看到,在此处shiro写入了SameSite属性,所以问题在于找出谁创建了SimpleCookie,那么只要设置这个SimpleCookie的SameSite为null就可以了。

再往下找到DefaultWebSessionManager这个类,在此类中调用了SimpleCookie的saveTo方法

    private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
        if (currentId == null) {
            String msg = "sessionId cannot be null when persisting for subsequent requests.";
            throw new IllegalArgumentException(msg);
        }
        Cookie template = getSessionIdCookie();
        Cookie cookie = new SimpleCookie(template);
        String idString = currentId.toString();
        cookie.setValue(idString);
        cookie.saveTo(request, response);
        log.trace("Set session ID cookie for session with id {}", idString);
    }

其中getSessionIdCookie方法为

    public Cookie getSessionIdCookie() {
        return sessionIdCookie;
    }

而在构造器中可以看到sessionIdCookie是在创建DefaultWebSessionManager的时候被初始化的 

    public DefaultWebSessionManager() {
        Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
        cookie.setHttpOnly(true); //more secure, protects against XSS attacks
        this.sessionIdCookie = cookie;
        this.sessionIdCookieEnabled = true;
        this.sessionIdUrlRewritingEnabled = true;
    }

所以问题的解决办法在于自定义DefaultWebSessionManager,创建一个自定义的SimpleCookie将SameSite属性设置为空即可

 

解决代码如下,我这里的话因为集成了哨兵redis,所以会有部分不相关的代码,你可以根据自己需要删除或者修改这部分的代码,但是重点SimpleCookie那一部分,根据需要可以自定义cookie的属性

有问题可以发我邮件哦417168602@qq.com

    @Bean
    public SessionManager sessionManager(RedisSentinelManager redisManager) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
        cookie.setHttpOnly(false);
        cookie.setSameSite(null);
        sessionManager.setSessionIdCookie(cookie);
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdUrlRewritingEnabled(true);
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager);
        sessionManager.setSessionDAO(redisSessionDAO);
        return sessionManager;
    }


    @Bean(name = "securityManager")
    public SecurityManager securityManager(RedisSentinelManager redisManager, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        List<Realm> realms = new ArrayList<>();
        realms.add(authRealm());
        realms.add(adminRealm());
        securityManager.setRealms(realms);
        securityManager.setSessionManager(sessionManager);
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        //缓存默认30分钟
        redisCacheManager.setRedisManager(redisManager);
        securityManager.setCacheManager(redisCacheManager);
        return securityManager;
    }

 

 

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值