美文网首页
【OpenGrok】Authorization based on

【OpenGrok】Authorization based on

作者: 87d6dc4b11a7 | 来源:发表于2024-10-14 10:24 被阅读0次

这是如何使用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授权头中的数据转换为请求中包含用户名的属性,以便堆栈中的其他插件可用。

当然,这可以通过使用项目组来实现。可以使用forProjectsforGroups属性的组合,使其真正灵活,更不用说在堆栈中添加更多插件或子堆栈的可能性。

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'

然后我们可以使用这些来执行查询。foobar项目被故意设置为包含一个名为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

相关文章

网友评论

      本文标题:【OpenGrok】Authorization based on

      本文链接:https://www.haomeiwen.com/subject/jbborjtx.html