opengrok的鑑權插件開發指南
opengrok是被廣泛應用的源代碼瀏覽系統。對於開源代碼,不需要考慮鑑權的問題,但是對於需要進行權限控制的代碼,我們就需要做一些鑑權操作。
opengrok專門爲我們提供了插件機制來進行鑑權等操作。
最簡單的鑑權例子
opengrok提供了IAuthorizationPlugin做爲鑑權的入口。IAuthorizationPlugin包含load, unload和兩個isAllowed方法,結構非常簡單。
第一步,我們先了解鑑權的接口。最簡單的鑑權操作,就是不管三七二十一一律通過。
我們實現接口如下:
public class TruePlugin implements IAuthorizationPlugin{
@Override
public void load(Map<String, Object> map) {
}
@Override
public void unload() {
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Project project) {
return true;
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Group group) {
return true;
}
}
我們可以通過把兩個isAllowed都改成返回false實現一個啥都不可以的鑑權。
load函數中的Map是配置項的引用。
isAllowed中的Project和Group是保存opengrok中的工程和工程組的數據結構。
插件落地之旅
插件寫好了之後,引用opengrok.jar和servlet api jar包就可以編譯成功了,畢竟我們一點有意義的邏輯都沒寫,想編不過也不太容易:)
插件堆棧
因爲opengrok支持多個插件,這些插件會形成一個插件堆棧。所以這些插件需要有一套邏輯來管理,否則就形成衝突了。
爲了更好地協調彼此,插件有下面三個屬性可以選擇:
- REQUIRED: 如果失敗,會導致最終鑑權失敗,但是會讓所有的插件都執行完
- REQUISITE: 如果失敗,則鑑權流程結束,不過失敗的原因會是第一個失敗的插件
- SUFFICIENT:如果當前插件成功,且之前沒有失敗,則直接返回成功
我們通過xml來寫這個屬性,我們舉個例子:
<void property="pluginStack">
<void method="add">
<object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
<void property="flag">
<string>REQUISITE</string>
</void>
<void property="name">
<string>com.ebanma.opengrok.plugin.TruePlugin</string>
</void>
</object>
</void>
</void>
這個pluginStack是Configuration的屬性,增加到configuration.xml中。
我們解釋下,我們相當於在pluginStack中調用add(AuthorizationPlugin)方法。
而flag和name的定義如下,定義在AuthorizationEntity類中,而AuthorizationPlugin繼承自AuthorizationEntity:
protected AuthControlFlag flag;
protected String name;
落地
我們將TruePlugin.class的按路徑放到data目錄的同級plugins目錄下。
這樣說有點抽象,我們看一個例子:
比如我的data目錄是:/workspace/xulun/opengrok/opengrok-1.3.6/data_dev_bsp_8155/,那麼plugin目錄就是/workspace/xulun/opengrok/opengrok-1.3.6/plugins
請看日誌中的打印:
org.opengrok.indexer.framework.PluginFramework.reload Plugins are being reloaded from /workspace/xulun/opengrok/opengrok-1.3.6/data_dev_bsp_8155/../plugins
爲了看得更清楚,我們打印幾行日誌,代碼最終如下:
package com.ebanma.opengrok.plugin;
import org.opengrok.indexer.authorization.*;
import org.opengrok.indexer.configuration.Group;
import org.opengrok.indexer.configuration.Project;
import java.util.Map;
public class TruePlugin implements IAuthorizationPlugin{
@Override
public void load(Map<String, Object> map) {
System.out.println("[xulun] BanmaGrok Plugin loaded");
}
@Override
public void unload() {
System.out.println("[xulun] BanmaGrok Plugin unloaded");
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Project project) {
System.out.println("[xulun] BanmaGrok Plugin verified 1");
return true;
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Group group) {
System.out.println("[xulun] BanmaGrok Plugin verified 2");
return true;
}
}
修改好configuration.xml後,我們重新deploy,例:
opengrok-deploy -c /workspace/xulun/opengrok/opengrok-1.3.6/etc/bsp_8155/configuration.xml -l DEBUG /workspace/xulun/opengrok/opengrok-1.3.6/lib/source.war /root/apache-tomcat-9.0.30/webapps/bsp_8155.war
我們查看tomcat的日誌catalina.out,看到如下:
25-Mar-2020 14:21:25.492 INFO [Catalina-utility-2] org.opengrok.indexer.framework.PluginFramework.reload Plugins are being reloaded from /workspace/xulun/opengrok/opengrok-1.3.6/data_dev_bsp_8155/../plugins
25-Mar-2020 14:21:25.494 INFO [Catalina-utility-2] org.opengrok.indexer.authorization.AuthorizationStack.load [REQUIRED] Stack "default stack" is loading.
[xulun] BanmaGrok Plugin loaded
25-Mar-2020 14:21:25.495 INFO [Catalina-utility-2] org.opengrok.indexer.authorization.AuthorizationPlugin.load [REQUISITE] Plugin "com.ebanma.opengrok.plugin.TruePlugin" found and is working.
25-Mar-2020 14:21:25.495 INFO [Catalina-utility-2] org.opengrok.indexer.authorization.AuthorizationStack.load [REQUIRED] Stack "default stack" is ready.
我們看到com.ebanma.opengrok.plugin.TruePlugin已經在正常工作了。
訪問之後,我們就能看到我們的輸出了:
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
[xulun] BanmaGrok Plugin allowed 1
好像看不出來啥,我們再把Project的信息打印出來:
代碼改成這樣:
package com.ebanma.opengrok.plugin;
import org.opengrok.indexer.authorization.*;
import org.opengrok.indexer.configuration.Group;
import org.opengrok.indexer.configuration.Project;
import java.util.Map;
public class TruePlugin implements IAuthorizationPlugin{
@Override
public void load(Map<String, Object> map) {
System.out.println("[xulun] BanmaGrok Plugin loaded");
}
@Override
public void unload() {
System.out.println("[xulun] BanmaGrok Plugin unloaded");
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Project project) {
System.out.println("[xulun] BanmaGrok Plugin verified 1:" + project.getName());
return true;
}
@Override
public boolean isAllowed(javax.servlet.http.HttpServletRequest httpServletRequest, Group group) {
System.out.println("[xulun] BanmaGrok Plugin verified 2:"+group.getName());
return true;
}
}
輸出如下:
[xulun] BanmaGrok Plugin verified 1:adsp_proc
[xulun] BanmaGrok Plugin verified 1:aop_proc
[xulun] BanmaGrok Plugin verified 1:boot_images
[xulun] BanmaGrok Plugin verified 1:btfm_proc
[xulun] BanmaGrok Plugin verified 1:btfm_proc_gen
[xulun] BanmaGrok Plugin verified 1:btfm_proc_hst
[xulun] BanmaGrok Plugin verified 1:btfm_proc_rome
[xulun] BanmaGrok Plugin verified 1:cdsp_proc
[xulun] BanmaGrok Plugin verified 1:cnss_proc
[xulun] BanmaGrok Plugin verified 1:common
[xulun] BanmaGrok Plugin verified 1:npu_proc
[xulun] BanmaGrok Plugin verified 1:trustzone_images
[xulun] BanmaGrok Plugin verified 1:venus_proc
[xulun] BanmaGrok Plugin verified 1:wdsp_proc
[xulun] BanmaGrok Plugin verified 1:wlan_proc_gen
[xulun] BanmaGrok Plugin verified 1:wlan_proc_hst
[xulun] BanmaGrok Plugin verified 1:apps_proc