记录一次微服务中使用SpringSecurity集成企业微信扫码登录-校验请求来源错误问题的解决
最近在项目中遇到一个平时不太注意的问题,记录一下方面后期继续深入跟踪,再近期项目中需要使用企业微信扫码登录,在将企业微信二维码嵌入到访问页面中的时候,结果二维码加载失败(校验请求来源错误),结果如下图所示。
场景复现
接入企业微信二维码方式
- 企业微信管理端添加访问白名单;
- 企业微信管理端设置可信域名(域名要保持和企业微信回调的域名相同)
- 必须要通过页面跳转打开访问生成企业微信二维码的链接
实现代码
登录页面(login.html)和跳转链接(忽略掉html布局略丑,单纯为了记录没有做美化)
1 | html复制代码<a href="https://testapi.xxxx.com/java/troy">企业微信</a> |
nginx配置
1 | nginx复制代码 location /java/login { |
springboot中springsecurity配置(这里省略掉其他配置)
1 | java复制代码@Bean |
controller
1 | java复制代码@Controller |
操作流程:
- 首先浏览器打开登录地址LoginController(“/java/login”)
- 进入登录页面login.html
- 点击页面链接进入TestController(“/java/troy”)进行跳转到企业微信API,然后企业微信内部调起生成二维码,页面呈现二维码用户扫码
抛析问题
在使用springsecurity方式失败后,项目组有同学通过go来调用,采用同样的操作流程缺直接打开了企业微信二维码扫码页面,期间也和同事在网上搜了一些二维码加载不出来的问题,但是可用的解决方案没有找到,提到的一些点又太粗,后面通过对比java和go的跳转链接发现,通过跳转后的链接,失败的时候没有http referer属性。既然发现不同点了,那么就好办了看一下springsecurity框架对于referer的处理,再看看能不能加的上,想到这里直接开动起来。
跳转请求对比
我们通过登录页面,执行操作流程中的第3步时,可以通过跳转链接抓到请求查看区别:
1 | sh复制代码#失败请求 |
通过对比发现失败的请求中缺少referer参数,通过查找springsecurity文档和源码发现,springsecurity会在response header中添加http referer策略,springsecurity默认使用的http referrer策略是ReferrerPolicy.NO_REFERRER。http referrer的介绍可以查看链接。那么到这里问题就简单了修改springsecurity配置,我是用的配置http referrer策略ReferrerPolicy.ORIGIN,大家可以按照自己项目需要选择合理的设置,这里简单讲一下这两个策略的意思,详细解释可以查看链接。
ReferrerPolicy.NO_REFERRER:no-referrer
整个 Referer 首部会被移除。访问来源信息不随着请求一起发送。(这也就解释了为什么失败的时候没有referer的值);
ReferrerPolicy.ORIGIN:origin 不管什么时候只使用origin作为引用地址。例如 www.troyqu.com/page.html的页面只会将www.troyqu.com作为引用地址。
解决问题
修改springboot中springsecurity配置
添加referrerPolicy(ReferrerPolicyServerHttpHeadersWriter.ReferrerPolicy.ORIGIN)
1 | java复制代码@Bean |
重启服务后访问发现,企业微信二维码可以打开了,到这里所有问题都彻底解决了。
那么既然springsecurity有设置http referer那么我们也可以对比下看看是不是更改配置后,对应的参数也进行了更新呢?
默认配置的控制台http参数
可以看到response header中的referer策略已经更新,设置为no-referrer(再次验证)
内部LoginController跳转到TestController接口的时候,request header中无referer参数。
修改后的控制台http参数
可以看到response header中的referer策略已经更新,设置为origin
内部LoginController跳转到TestController接口的时候,request header中referer参数值也和origin一样,没有其他的http path信息。
总结
- springsecurity默认使用ReferrerPolicy.NO_REFERRER:no-referrer的策略,当我们需要访问一些其他厂商的API需要验证referrer的时候,会因为请求缺少referrer导致请求被验证不合法,从而导致请求处理失败。
- 之前对于http referrer参数没有进行太深入了解,后面需要补一下相关知识。
本文转载自: 掘金