这是如何使用Tomcat应用程序服务器将Authorization框架与HTTP Basic Authentication一起使用的示例。
正如授权wiki中提到的,OpenGrok不执行身份验证(authentication),只执行授权(authorization)。认证步骤将由OpenGrok之上的某一层执行,例如应用服务器、反向代理等。
创建两个演示项目
mkdir /opengrok/src/{foo,bar}
cd /opengrok/src
echo greenparrot > foo/data.txt
echo greenparrot > bar/data.txt
设置Tomcat Setting up Tomcat
Tomcat支持基本身份验证(根据RFC 7617)。虽然在这种特殊情况下,Tomcat可以同时提供身份验证和授权,但建议始终在OpenGrok web应用程序中配置授权,因为它知道需要进行授权的所有位置,这是应用程序服务器无法知道的。
Tomcat users
在本例中,我们将定义两个用户。每个用户只能访问与其用户名匹配的项目。
我们必须修改Tomcat文件,以提供有关系统中用户和角色的信息。该文件位于$CATALINA_BASE/conf/tomcat-users.xml中。在本例中,将这些行添加到元素<tomcat-users>中的文件中。整个文件看起来像这样:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<user username="foo" password="foo" roles="tomcat,manager-script"/>
<user username="bar" password="bar" roles="tomcat,manager-script"/>
<user username="root" password="root" roles="tomcat,manager-script"/>
</tomcat-users>
Application deployment descriptor
现在我们必须告诉应用程序,它应该使用HTTP Basic authentication来验证其源。我们可以通过修改web.xml文件来做到这一点,该文件通常放在应用程序的WEB-INF目录中。一旦部署了web应用程序,就会创建这个目录。
插入以下几行到web.xml文件中(在顶层web-app XML元素下),使其工作:
<security-constraint>
<web-resource-collection>
<web-resource-name>API endpoints are checked separately by the web app</web-resource-name>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>In general everything needs to be authenticated</web-resource-name>
<url-pattern>/*</url-pattern> <!-- protect the whole application -->
<url-pattern>/api/v1/search</url-pattern> <!-- protect search endpoint whitelisted above -->
<url-pattern>/api/v1/suggest/*</url-pattern> <!-- protect suggest endpoint whitelisted above -->
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-role>
<role-name>*</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
此配置确保Tomcat将请求指定url的身份验证。role-name元素中的星号将使Tomcat只执行身份验证。通过身份验证的用户的细粒度授权将由OpenGrok web应用程序本身执行。这是配置授权的推荐方法。
请记住,每次重新部署时都需要重新插入这些内容,因为文件将被源文件中的内容覆盖source.war文件。opengrok-deploy脚本将在这方面提供帮助——只需使用--insert选项:
opengrok-deploy --insert insert.xml source.war \
/path/to/your/application/server/webapps/newsrc.war
Web application configuration
必要配置:
- 插件目录路径:这是在发行版存档中找到的
plugins.jar文件需要放置的位置 - authorization堆栈
- 白名单:我们将使用一个授权插件,它将根据白名单检查用户,看看他们是否被授权查看给定的项目。在本例中,白名单存储在
/opengrok/etc目录中。白名单是一个简单的文本文件,每一行都是一个用户名。
创建白名单:
echo foo > /opengrok/etc/foo-whitelist.txt
echo root >> /opengrok/etc/foo-whitelist.txt
echo bar > /opengrok/etc/bar-whitelist.txt
echo root >> /opengrok/etc/bar-whitelist.txt
现在让我们将以下内容保存到/opengrok/etc/readonly-configuration.xml中(用作只读配置):
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_60" class="java.beans.XMLDecoder">
<object class="org.opengrok.indexer.configuration.Configuration" id="Configuration0">
<void property="pluginDirectory">
<string>/opengrok/dist/share/lib</string>
</void>
<void property="pluginStack">
<void property="stack">
<!-- get user cred from HTTP headers -->
<void method="add">
<object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
<void property="name">
<string>opengrok.auth.plugin.UserPlugin</string>
</void>
<void property="flag">
<string>REQUISITE</string>
</void>
<void property="setup">
<void method="put">
<string>decoder</string>
<string>opengrok.auth.plugin.decoders.UserPrincipalDecoder</string>
</void>
</void>
</object>
</void>
<void method="add">
<object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
<void property="forProjects">
<void method="add">
<string>foo</string>
</void>
</void>
<void property="name">
<string>opengrok.auth.plugin.UserWhiteListPlugin</string>
</void>
<void property="flag">
<string>REQUIRED</string>
</void>
<void property="setup">
<void method="put">
<string>file</string>
<string>/opengrok/etc/foo-whitelist.txt</string>
</void>
</void>
</object>
</void>
<void method="add">
<object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
<void property="forProjects">
<void method="add">
<string>bar</string>
</void>
</void>
<void property="name">
<string>opengrok.auth.plugin.UserWhiteListPlugin</string>
</void>
<void property="flag">
<string>REQUIRED</string>
</void>
<void property="setup">
<void method="put">
<string>file</string>
<string>/opengrok/etc/bar-whitelist.txt</string>
</void>
</void>
</object>
</void>
</void>
</void>
</object>
</java>
授权插件目录设置为/opengrok/dist/share/lib/auth/plugins。同样,这是假设来自https://github.com/opengrok/opengrok/wiki/How-to-setup-OpenGrok的目录结构。该目录可以包含提取的插件类(在各自的目录结构中)和带有授权插件的JAR文件。在这种情况下,解压的发行版在插件目录中只有一个plugins.jar文件。
注意,堆栈中的第一个插件被定义为使用HttpBasicAuthHeaderDecoder。这个解码器将Tomcat生成的HTTP授权头中的数据转换为请求中包含用户名的属性,以便堆栈中的其他插件可用。
当然,这可以通过使用项目组来实现。可以使用forProjects和forGroups属性的组合,使其真正灵活,更不用说在堆栈中添加更多插件或子堆栈的可能性。
Deploy
Index
现在运行Indexer。有必要在授权堆栈配置中使用-R选项。例如,Indexer选项将是:
-s
/opengrok/src
-d
/opengrok/data
-P
-H
-S
-G
-R
/opengrok/etc/readonly_configuration.xml
-W
/opengrok/etc/configuration.xml
-U
http://localhost:8080/source
请注意,还有其他方法可以在不运行索引器的情况下使只读配置生效。这样做只是为了简单。也就是说,请记住,索引器每次都必须使用-R选项运行,除非使用以项目为中心的使用存储库同步脚本的工作流。
在Indexer运行结束时,web应用程序将重新加载其配置,授权堆栈将生效。在日志文件中(如catalina.out(在Tomcat中),日志条目看起来像这样:
26-Aug-2019 13:19:21.635 INFO [http-nio-8080-exec-3] org.opengrok.indexer.framework.PluginFramework.reload Plugins are being reloaded from /opengrok/dist/share/lib
26-Aug-2019 13:19:21.645 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.LdapUserPlugin is not configured in the stack
26-Aug-2019 13:19:21.651 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.LdapFilterPlugin is not configured in the stack
26-Aug-2019 13:19:21.653 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.TruePlugin is not configured in the stack
26-Aug-2019 13:19:21.668 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.HttpBasicAuthorizationPlugin is not configured in the stack
26-Aug-2019 13:19:21.678 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.FalsePlugin is not configured in the stack
26-Aug-2019 13:19:21.685 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationFramework.classLoaded plugin opengrok.auth.plugin.LdapAttrPlugin is not configured in the stack
26-Aug-2019 13:19:21.689 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationStack.load [REQUIRED] Stack "default stack" is loading.
26-Aug-2019 13:19:21.693 INFO [http-nio-8080-exec-3] opengrok.auth.plugin.UserPlugin.load loading decoder: opengrok.auth.plugin.decoders.UserPrincipalDecoder
26-Aug-2019 13:19:21.694 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationPlugin.load [REQUISITE] Plugin "opengrok.auth.plugin.UserPlugin" found and is working.
26-Aug-2019 13:19:21.695 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationPlugin.load [REQUIRED] Plugin "opengrok.auth.plugin.UserWhiteListPlugin" found and is working.
26-Aug-2019 13:19:21.696 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationPlugin.load [REQUIRED] Plugin "opengrok.auth.plugin.UserWhiteListPlugin" found and is working.
26-Aug-2019 13:19:21.696 INFO [http-nio-8080-exec-3] org.opengrok.indexer.authorization.AuthorizationStack.load [REQUIRED] Stack "default stack" is ready.
Test
一旦索引器完成其工作并将新的配置发送给web应用程序,授权配置将生效。我们可以同时使用web UI和RESTful API进行测试。
Using web UI
例如,在Firefox中,打开新的Private窗口,输入用户凭证并检查web应用程序索引页上的项目列表。
Using RESTful API
我们将需要base64编码的用户名和密码,因为这是HTTP Basic authentication的工作方式:
$ python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.encodestring(b"foo:foo")
b'Zm9vOmZvbw==\n'
>>> base64.encodestring(b"root:root")
b'cm9vdDpyb290\n'
>>> base64.encodestring(b"bar:bar")
b'YmFyOmJhcg==\n'
然后我们可以使用这些来执行查询。foo和bar项目被故意设置为包含一个名为data.txt的文件,具有相同的内容(字符串greenparrot),所以让我们看看授权堆栈是否工作:
# try user foo
$ curl -H 'Authorization: Basic Zm9vOmZvbw==' -s 'http://10.x.y.z:8080/source/api/v1/search?full=greenparrot' | jq
{
"time": 38,
"resultCount": 1,
"startDocument": 0,
"endDocument": 0,
"results": {
"/foo/data.txt": [
{
"line": "<b>greenparrot</b>",
"lineNumber": "1"
}
]
}
}
# try user bar
$ curl -H 'Authorization: Basic YmFyOmJhcg==' -s 'http://10.x.y.z:8080/source/api/v1/search?full=greenparrot' | jq
{
"time": 74,
"resultCount": 1,
"startDocument": 0,
"endDocument": 0,
"results": {
"/bar/data.txt": [
{
"line": "<b>greenparrot</b>",
"lineNumber": "1"
}
]
}
}
# try user root
$ curl -H 'Authorization: Basic cm9vdDpyb290' -s 'http://10.x.y.z:8080/source/api/v1/search?full=greenparrot' | jq
{
"time": 12,
"resultCount": 2,
"startDocument": 0,
"endDocument": 1,
"results": {
"/bar/data.txt": [
{
"line": "<b>greenparrot</b>",
"lineNumber": "1"
}
],
"/foo/data.txt": [
{
"line": "<b>greenparrot</b>",
"lineNumber": "1"
}
]
}
}
注意,对于对/search端点的RESTful API调用,没有指定任何项目,因此web应用程序搜索用户授权的所有项目。如预期的那样,用户foo可以看到或搜索项目foo,用户栏项目栏和用户根都可以看到项目foo。
参考链接:
https://github.com/oracle/opengrok/wiki/Authorization-based-on-HTTP-Basic-Authentication















网友评论