背景
公司一直使用confluence來進(jìn)行內(nèi)部知識(shí)管理絮识。老板突然想用飛書扣墩,然后讓我將confluence與飛書打通座硕。因此開始了解confluence和飛書的打通問題闰挡。
confluence sso 基礎(chǔ)知識(shí)
Jira和Confluence集成了Atlassian自己開的一套SSO系統(tǒng)——Seraph。Seraph是由Atlassian開發(fā)的非常簡(jiǎn)單析校,可插入的J2EE 網(wǎng)頁安全應(yīng)用框架构罗,它被廣泛使用在Atlassian的產(chǎn)品中。
Seraph允許你寫自定義的認(rèn)證器智玻,來將confluence/jira與你的系統(tǒng)來打通遂唧。
下圖是Confluence認(rèn)證的流程圖,大體流程如下:
- 嘗試通過request的passord和密碼登錄
- 嘗試通過已經(jīng)存在的session進(jìn)行登錄
- 嘗試通過 cookie登錄
- 嘗試通過http ba認(rèn)證登錄
由于Authenticator.login(request, response, username, password, rememberMe)
這個(gè)方法出現(xiàn)了三次吊奢,看起來有點(diǎn)復(fù)雜盖彭。所以它已經(jīng)被分解到了自己的子流程中。如下為登錄的子流程:
支持的認(rèn)證方法
如上述流程圖所示页滚,默認(rèn)的Seraph認(rèn)證支持四種認(rèn)證方法:
- 請(qǐng)求參數(shù)召边。
os_username
和os_password
。 - session屬性儲(chǔ)存登錄用戶裹驰。
- cookie存儲(chǔ)
username
和password
(remember me
登錄) - 通過標(biāo)準(zhǔn)的http頭進(jìn)行Http ba認(rèn)證
每個(gè)方法按上述流程圖的順序進(jìn)行嘗試隧熙。前面的方法成功登錄后,會(huì)略過后續(xù)的登錄流程幻林。某個(gè)登錄失敗后贞盯,會(huì)依次嘗試后續(xù)的方法直到所有的都失敗。此時(shí)滋将,用戶被認(rèn)為是“匿名用戶”邻悬,并按Confluence中的匿名用戶的權(quán)限進(jìn)行處理。我們需要覆蓋該方法随闽,并在后面加上對(duì)應(yīng)的與飛書的http認(rèn)證就可以了父丰。
參照源代碼可以看出,Seraph支持基于角色的認(rèn)證掘宪,但是這個(gè)在confluence中僅被用來鑒權(quán) /admin/ URL的訪問權(quán)限(如果要使用飛書的管理員蛾扇,可以用這個(gè))。
代碼流程講解
在系統(tǒng)中魏滚,上述的代碼流程在com.atlassian.confluence.user.ConfluenceAuthenticator
中镀首,我們?nèi)绻枰远xhttp認(rèn)證,需要如下的流程:
- 寫一個(gè)類鼠次,繼承自
com.atlassian.confluence.user.ConfluenceAuthenticator
, 覆蓋其getUser
方法, 參考代碼seraph更哄。(注意芋齿,示例中繼承的類是DefaultAuthenticator
, 這個(gè)是在confluence 2.2及以下才可以,其余的請(qǐng)繼承com.atlassian.confluence.user.ConfluenceAuthenticator
) - 將代碼打包成jar放置于
confluence安裝目錄/WEB-INF/lib/
下(或者將類放入WEB-INF/classes/下成翩,我沒試過是否OK)觅捆。 - 打開
confluence安裝目錄/WEB-INF/classes/seraph-config.xml
, 修改如下內(nèi)容:
<security-config>
<parameters>
<init-param>
<param-name>login.url</param-name>
<!--把登錄url改為飛書的登錄鏈接,appid填你的網(wǎng)頁app的appid-->
<param-value>https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=${originalurl}&app_id=&state=</param-value>
</init-param>
<init-param>
<param-name>link.login.url</param-name>
<!--鏈接同上-->
<param-value>https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=${originalurl}&app_id=&state=</param-value>
</init-param>
<!-- 其它配置省略麻敌,不用動(dòng)-->
</parameters>
<!-- 其它配置省略栅炒,不用動(dòng)-->
<!--
修改認(rèn)證器的class, 指向自己寫的子類
<authenticator class="com.atlassian.confluence.user.ConfluenceAuthenticator"/>
-->
<authenticator class="com.example.test.xxConfluenceAuthenticator"/>
<!-- 其它配置省略 -->
</security-config>
- 保存,并重啟confluence术羔。登錄后赢赊,系統(tǒng)會(huì)跳轉(zhuǎn)到飛書登錄頁。
- 這種情況下级历,confluence的首頁會(huì)變?yōu)轱w書的登錄頁释移,我們可以通過飛書來登錄了。但是還有個(gè)問題寥殖,confluence并不會(huì)關(guān)掉之前的用戶名密碼登錄秀鞭,用戶還是可以訪問那個(gè)頁面。我們可以在nginx下加上對(duì)應(yīng)的處理扛禽,來關(guān)掉這個(gè)頁面的訪問(apache自行按對(duì)應(yīng)規(guī)則處理):
location /login.action {
// 釘釘,飛書等的登錄跳回時(shí)皱坛,會(huì)帶上code作為登錄憑證编曼,普通用戶不會(huì)。因此直接將所有不帶code訪問login的請(qǐng)求rewrite
if ($args !~ code=){
rewrite ^ http://xx.com/;
}
}
總結(jié)
整體流程很簡(jiǎn)單剩辟,基本就是寫個(gè)認(rèn)證的子類掐场,然后把配置中的類指向我們寫的子類即可。麻煩的部分是如何構(gòu)建一個(gè)confluence的開發(fā)測(cè)試環(huán)境贩猎,并且如何調(diào)用confluence的類熊户,這一部分,下次再寫吧吭服。