关于带Cookie的跨域问题导致Shiro授权和认证失败的问题

问题描述:后端框架为SpringBoot,安全框架为Shiro。其中认证和授权都已经做好了,授权和认证主要是用注解的方式,主要采用了@RequiresAuthentication这个注解,意思是加上这个注解的方法,必须经过授权才可以访问,也就是必须登陆才可以。之后整个项目只用了Postman进行测试。

主要测试就是两方面,在不登陆的情况下去访问带有@RequiresAuthentication的方法,会返回没有权限。在登陆之后,就可以访问得到相应的资源。在postman测试完了之后,就以为Shiro配置完毕了。

后来,项目在线上进行测试的时候就发现问题了,也就是登陆之后(登录是成功的),在访问带有@RequiresAuthentication仍然报没有权限。。后来也进行了一些断点测试,就发现了SecurityUtils.getSubject().getPrincipal()在登陆之后是存在的,但是如果是另外一个请求这个值就是空的。。。

本来我在自己的印象里,shiro的操作是线程相关的,也就是可以通过线程来区分是哪个用户在操作。但是线程是多大的呢。。是每一个Http请求都新建一个线程吗?显然我觉得这是不可能的,但是我又找不到证据,所以就开始找资料,后来找到了这篇。https://blog.csdn.net/quanaianzj/article/details/83858575,这一片很详细的解释了Shiro的工作原理。直接看最终的结论:

也就是说,每次的subject内的用户信息,是从session中读取的,所以既然跟session有关系。前端发送的请求就必须带上jsessionid,这个是session的唯一凭证,一般这些事情都是浏览器帮你做好的。但是自己翻了翻浏览器的cookie发现自己并没有找到相关的cookie,但是在postman中找到了,如下图

所以走到这我就更加坚信了,是因为某种原因导致前端请求发送的时候没有带上cookie,或者说是登陆之后,后端根本就没有返回相应的cookie。。因为伟哥在他浏览器上测试也是没有cookie,所以到这我就知道应该是我后端的原因,而不是浏览器的问题。。后来终于发现罪魁祸首是跨域问题。参考如下http://www.cnblogs.com/nuccch/p/7875189.html。如下图

也就是说,当请求是跨域的,并且是用CORS协议解决的话,http请求或者ajax请求是不会带上服务器返回的cookie的,也就是说每一个ajax请求在后端看来都是一个全新的请求,都会创建一个新的session,而Shiro的用户认证信息都是放在session中的,所以信息自然也就找不到了,相应的认证也就会失败。。所以到此,解决问题的方案就是想办法让ajax请求的时候带上cookie。

经过查阅资料,需要在ajax请求中加入一个字段,如下图

加上一个xhrFields字段,意思是带上cookie一起发送。同样还需要在后端的解决跨域过滤器上加上一条语句,如下图

加上一个setAllowCredentials(true)。到此,本以为问题会解决,但是再次发送请求的时候仍然会出现错误。如下图

大意就是如果带上了cookie的请求,你后端的allowOrigin就不能设置成"*"了,所以就必须明确指定请求来源的哪个域。这就比较简单了,一般来说origin就是域名,本地请求话就是http://localhost: + 端口号。所以修改后端代码如下

至此,问题全部解决!当然了,上述直接把域名硬编码到代码中也是不优雅的,可以origin写入application.yml中去读取,域名修改的时候只需要修改配置文件就可以了。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值