Skip to content

Conversation

@vladak
Copy link
Member

@vladak vladak commented Jul 24, 2019

This change introduces new simple authorization plugin that checks user against a whitelist. It complements/depends on the HTTP Basic Auth decoder (PR #2875).

The idea was spawned by the discussion in #2872. Basically, it allows to shift authorization decision from Tomcat to OpenGrok authorization framework for setup where authentication is done by Tomcat.

@vladak
Copy link
Member Author

vladak commented Jul 24, 2019

Testing setup:
conf/tomcat-users.xml contained:

  <user username="foo" password="bar" roles="tomcat,manager-script"/>           
  <user username="bar" password="foo" roles="tomcat,manager-script"/>  

and the indexer was run with:

-s
/var/opengrok/src
-d
/var/opengrok/data
-P
-H
-S
-G
-R
/var/opengrok/etc/readonly_configuration-BasicHttpAuth.xml
-W
/var/opengrok/etc/configuration.xml
-U
http://localhost:8080/source

where the readonly_configuration-BasicHttpAuth.xml contained:

  <void property="pluginStack">
        <void property="stack">
            <!-- get user cred from HTTP headers -->
            <void method="add">
                <object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
                <!--
                    <void property="forGroups">
                            <void method="add">
                                <string>Solaris</string>
                            </void>
                    </void>
                    <void property="forProjects">
                            <void method="add">
                                <string>solaris-userland</string>
                            </void>
                    </void>
                -->
                    <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.HttpBasicAuthHeaderDecoder</string>
                        </void>
                    </void>
                </object>
            </void>

            <void method="add">
                <object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
                <!--
                    <void property="forGroups">
                            <void method="add">
                                <string>Solaris</string>
                            </void>
                    </void>
                    <void property="forProjects">
                            <void method="add">
                                <string>solaris-userland</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>/var/opengrok/etc/user-whitelist.txt</string>
                        </void>
                    </void>
                </object>
            </void>

        </void>
  </void>

with /var/opengrok/etc/user-whitelist.txt having just a single line:

foo

and the following was inserted to WEB-INF/web.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>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>

This setup enforced the authentication in Tomcat and authorization in OpenGrok.

Using the /search API endpoint for testing the foo user first:

$ http_proxy= curl -H 'Authorization: Basic Zm9vOmJhcg==' -s 'http://10.x.y.z:8080/source/api/v1/search?full=hack&projects=solaris-userland&projects=jna' | jq
{
  "time": 1434,
  "resultCount": 67,
  "startDocument": 0,
  "endDocument": 66,
  "results": {
    "/solaris-userland/components/x11/lib/libdga/sun-src/dga_Xrequests.c": [
      {
        "line": "#define X_DGA 0 /* a <b>hack</b>, so GetReq and GetResReq work below */",
        "lineNumber": "74"
      }
    ],
...

and then the bar user:

$ http_proxy= curl -H 'Authorization: Basic YmFyOmZvbw==' -s 'http://10.x.y.z:8080/source/api/v1/search?full=hack&projects=solaris-userland&projects=jna' | jq
{
  "time": 19,
  "resultCount": 0,
  "startDocument": 0,
  "endDocument": -1,
  "results": {}
}

Obviously this can be made more fine grained by uncommenting the forProjects and forGroups parts in the read-only configuration.

@vladak
Copy link
Member Author

vladak commented Jul 24, 2019

Once this is merged in, I will update the Authorization wiki.

@vladak
Copy link
Member Author

vladak commented Jul 24, 2019

@tulinkry thanks for the review, could you take a look at #2875 also as this one depends on it ?

@vladak vladak merged commit 8ef7bc0 into oracle:master Jul 24, 2019
@vladak vladak deleted the user_whitelist_plugin branch July 24, 2019 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants