userRealm含有遠(yuǎn)程微服務(wù)時(shí)的配置
userRealm如果含有遠(yuǎn)程微服務(wù),通過普通的configuration方式,在Java代碼中new一個(gè)對象,將不能獲取遠(yuǎn)程微服務(wù)。根據(jù)
http://blog.csdn.net/leiyong0326/article/details/52036736
之描述,Spring的Java配置方式會先于掃描注解(例如@Reference)執(zhí)行。所以會造成SecurityManager中的UserRealm無遠(yuǎn)程微服務(wù)的代理(句柄)。
解決方法是回歸到配置文件的方式,具體的配置如下

這時(shí)Java配置的部分已經(jīng)不需要了。此時(shí)注意,如果Shiro配置還以Java的方式呈現(xiàn),那么會首先執(zhí)行Java代碼,再初始化配置文件。所以要把shiro配置也改為配置文件才行。但例如Cache等不影響的bean還是可以用Java來配置。
由于定義了微服務(wù),所以UserRealm中只需要@Autowired即可,這樣處理后,就可以在運(yùn)行時(shí)得到遠(yuǎn)程微服務(wù)的句柄了。
在試驗(yàn)成功后又有了一個(gè)小插曲,發(fā)現(xiàn)如果在ShiroConf中有以下定義

還是會先初始化UserRealm,去掉即可。不過考慮到以后可能會出現(xiàn)Annotation不生效的情況,可能會把所有配置還是都轉(zhuǎn)換到配置文件中去。這點(diǎn)拭目以待吧。
Filter配置的改變
在根據(jù)以上調(diào)整,使用spring-shiro.xml后,F(xiàn)ilter配置如果不修改的話,spring boot會加入多個(gè)filter。

所以在內(nèi)存的FilterChain會注入多余的filter,如下圖所示(紅框?yàn)槎嘤嗟腇ilter):

根據(jù)
https://www.oschina.net/question/250720_195683
的描述,原因就是,value-ref不會調(diào)用已有的bean,會生成新的bean。所以必須修改成內(nèi)部聲明的方式才可以,如下圖所示:


從這里可以看出多余的filter已經(jīng)不存在了,且可以正常的進(jìn)入controller。這也說明Spring boot雖然還用配置文件,但解析的時(shí)候還是按結(jié)構(gòu)大量的new對象,reference這種方式貌似是不支持的。
SimpleSession的序列化問題
這個(gè)問題拖了比較久的時(shí)間,SimpleSession這個(gè)對象在實(shí)現(xiàn)的時(shí)候,自己定義了readObject和writeObject,且把屬性都做成了transient,如下圖所示:

但是Dubbo做遠(yuǎn)程調(diào)用(亦或是Spring boot的原因)序列化時(shí)并沒有運(yùn)行自己的readObject/writeObject方法,導(dǎo)致數(shù)據(jù)無法傳輸具體原因未知。
改進(jìn)的方法是生成一個(gè)子類MySimpleSession,單例模式生成對象,所有的屬性復(fù)制過來,實(shí)際測試發(fā)現(xiàn)這些屬性的值也就有了。如下圖所示

客戶端無法獲取登錄信息的問題(已解決)
登錄后,客戶端的subject無法獲取到登錄后的信息,例如Principle。分析原因,開始以為是跨域問題,后來發(fā)現(xiàn)這個(gè)信息是從session中遠(yuǎn)程獲取的。繼而懷疑在server端沒有置入這個(gè)登錄后的subject,但是查看后發(fā)現(xiàn)已經(jīng)置入了。最后發(fā)現(xiàn)獲取session的id是通過request的cookie獲取的,但是request根本沒有這個(gè)cookie,不論是用內(nèi)置的tomcat還是Jetty,以及在命令行模式還是debug模式。
這個(gè)問題可以用另外的方式解決,即在前端把sessionID作為parameter放到request中即可。