userRealm含有远程微服务时的配置
userRealm如果含有远程微服务,通过普通的configuration方式,在Java代码中new一个对象,将不能获取远程微服务。根据
http://blog.csdn.net/leiyong0326/article/details/52036736
之描述,Spring的Java配置方式会先于扫描注解(例如@Reference)执行。所以会造成SecurityManager中的UserRealm无远程微服务的代理(句柄)。
解决方法是回归到配置文件的方式,具体的配置如下
引入配置文件这时Java配置的部分已经不需要了。此时注意,如果Shiro配置还以Java的方式呈现,那么会首先执行Java代码,再初始化配置文件。所以要把shiro配置也改为配置文件才行。但例如Cache等不影响的bean还是可以用Java来配置。
由于定义了微服务,所以UserRealm中只需要@Autowired即可,这样处理后,就可以在运行时得到远程微服务的句柄了。
在试验成功后又有了一个小插曲,发现如果在ShiroConf中有以下定义
Advisor的定义还是会先初始化UserRealm,去掉即可。不过考虑到以后可能会出现Annotation不生效的情况,可能会把所有配置还是都转换到配置文件中去。这点拭目以待吧。
Filter配置的改变
在根据以上调整,使用spring-shiro.xml后,Filter配置如果不修改的话,spring boot会加入多个filter。
未修改的配置所以在内存的FilterChain会注入多余的filter,如下图所示(红框为多余的Filter):
FilterChain的内容根据
https://www.oschina.net/question/250720_195683
的描述,原因就是,value-ref不会调用已有的bean,会生成新的bean。所以必须修改成内部声明的方式才可以,如下图所示:
修改后的配置 FilterChain的内容从这里可以看出多余的filter已经不存在了,且可以正常的进入controller。这也说明Spring boot虽然还用配置文件,但解析的时候还是按结构大量的new对象,reference这种方式貌似是不支持的。
SimpleSession的序列化问题
这个问题拖了比较久的时间,SimpleSession这个对象在实现的时候,自己定义了readObject和writeObject,且把属性都做成了transient,如下图所示:
transient关键字导致属性不被序列化但是Dubbo做远程调用(亦或是Spring boot的原因)序列化时并没有运行自己的readObject/writeObject方法,导致数据无法传输具体原因未知。
改进的方法是生成一个子类MySimpleSession,单例模式生成对象,所有的属性复制过来,实际测试发现这些属性的值也就有了。如下图所示
MySimpleSession解决属性问题客户端无法获取登录信息的问题(已解决)
登录后,客户端的subject无法获取到登录后的信息,例如Principle。分析原因,开始以为是跨域问题,后来发现这个信息是从session中远程获取的。继而怀疑在server端没有置入这个登录后的subject,但是查看后发现已经置入了。最后发现获取session的id是通过request的cookie获取的,但是request根本没有这个cookie,不论是用内置的tomcat还是Jetty,以及在命令行模式还是debug模式。
这个问题可以用另外的方式解决,即在前端把sessionID作为parameter放到request中即可。
网友评论