升级Shiro到1.7.1版本中出现的问题

1,730 阅读3分钟

记录升级Shiro版本后,出现的一些问题

项目原本使用的Shiro是1.3.0版本的,而shiro官方发布了Apache Shiro权限绕过漏洞(CVE-2020-17523)风险通告。使用shiro和spring的用户都需升级到最新的shiro-1.7.1版本。
于是在pom.xml中修改了版本号之后重新发布了项目,并进行了测试。测试中发现了一些因升级shiro版本出现的问题,在此记录。

URL中存在中文的请求被拦截

测试接口时发现,原来的部分接口会将中文参数拼接在URL路径上,如/hello/你好,这种请求方式在低版本shiro没有问题,而升级后却出现请求被拦截了。
后经过查阅资料与阅读源码后发现,1.7.1版本的ShiroFilterFactoryBeanglobalFilters中默认加载了一个InvalidRequestFilter.

image.png

Filter的第三次校验中,调用的request.getPathInfo()会将原本编码过的url重新解码,isValid()负责校验url是否存在非Ascii编码的字符,所以就是在这里请求被拦截了。

image.png

解决方式

  1. 如果存在较少的URL不规范的话,还是建议修改URL,将中文以参数的格式发送,如/hello?key=你好。
  2. 如果不想大范围的排查URL规范,可以修改这个ShiroFilterFactoryBean,将InvalidRequestFilter移除。下面贴出我的实现。

image.png

重定向次数过多

部分用户反应一些接口出现重定向次数过多报错。 经过排查,发现了一个重定向的请求中Response Headers中的一个响应头Set-Cookie的值里面有SameSite=lax这个属性。该属性是浏览器用来防止CSRF攻击的,当使用第三方cookie时,该属性的值会决定是否允许发送cookie,详情见:www.ruanyifeng.com/blog/2019/0…
而系统中的单点登入是接的第三方的,登录后会返回一个cookie,而我们的系统在请求时会携带这个cookie,表示用户已经登录成功了。
但我们的系统和第三方的系统不在一个网段,请求存在跨域,而单点登录的cookie对我们系统来说成了第三方cookie,被浏览器禁止发送了。
然后就变成:请求后台接口(未携带cookie)-> 判断是否登入 -> 未登录,重定向到登录系统(这时会记录跳转来时的接口,以便登录后再跳回去) -> 判断是否登入(由于登陆系统就是第三方的,所以这次会携带cookie) -> 已登录 -> 跳转到请求的接口(未携带cookie)--> 后面就死循环了,直到报错。

哪里设置了SameSite?

通过查看代码发现系统使用了org.apache.shiro.web.servlet.SimpleCookie来设置cookie。这里默认为san'me

image.png

解决方式

  1. 将请求换成https请求,并将SameSite值设为none。(没试过)
  2. 将这个默认的值设为null。

image.png

本人采用的方式的并不好,从某种程度上会降低系统的安全,如果有更好的方式希望能够分享给我。