Skip to content

Authorization plugins

Vladimir Kotal edited this page Sep 3, 2019 · 21 revisions

The authorization framework would be useless without set of plugins. OpenGrok ships with basic set of plugins that allow for definition of flexible authorization stacks.

Generic plugins

UserPlugin

The UserPlugin constructs a User object and sets it as a request attribute. This object can be then used by other plugins down the stack. The object is constructed using properties of the request, namely its attributes and/or HTTP headers. The User object has 2 main properties: id and username. The can be expanded by other plugins using %guid% and %username%, respectively.

Decoders

Name Purpose
UserPrincipalDecoder uses getRemoteUser() Java EE API to retrieve information about the user. This works for example for the HTTP Basic authentication.
MellonHeaderDecoder decodes mod_mellon HTTP headers, namely MELLON_email (id) and MELLON_username (username)
OSSOHeaderDecoder decodes Oracle SSO HTTP headers, namely osso-subscriber-dn (username) and osso-user-guid (id)

Example configuration

            <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.MellonHeaderDecoder</string>
                        </void>
                    </void>
                </object>
            </void>

UserWhiteListPlugin

Checks username of the User object against a whitelist stored in text file (one username per line). This plugin depends on the UserPlugin (which sets the User object as a request attribute) so it needs to be in the stack below.

Example configuration

<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>

LDAP plugins

Each of the LDAP plugins performs a query to LDAP server to determine whether to allow the request.

LDAP setup

All LDAP plugins can use distinct LDAP server configuration. The configuration is put info effect by using the setup property, for example:

        <void property="setup">
            <void method="put">
                <string>configuration</string>
                <string>/opengrok/auth/config/ldap-plugin-config-corp.xml</string>
            </void>
        </void>

and the ldap-plugin-config-corp.xml file can have these contents:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_65" class="java.beans.XMLDecoder">
        <object class="opengrok.auth.plugin.configuration.Configuration">
                <void property="interval">
                        <int>900000</int>
                </void>
                <void property="searchBase">
                        <string>dc=foo,dc=com</string>
                </void>
                <void property="webHooks">
                 <object class="opengrok.auth.plugin.util.WebHooks">
                  <void property="fail">
                   <object class="opengrok.auth.plugin.util.WebHook">
                    <void property="URI">
                     <string>http://localhost:8080/source/api/v1/messages</string>
                    </void>
                    <void property="content">                                                 
                     <string>{ "tags": [ "main" ], "cssClass": "class", "text": "corporate LDAP failed", "duration": "PT10M" }</string>
                    </void>
                   </object>
                  </void>
                 </object>
                </void>
                <void property="countLimit">
                 <int>10</int>
                </void>
                <void property="connectTimeout">
                 <int>3000</int>
                </void>
                <void property="searchTimeout">
                 <int>3000</int>
                </void>
                <void property="servers">
                        <void method="add">
                                <object class="opengrok.auth.plugin.ldap.LdapServer">
                                        <void property="name">
                                                <string>ldap://ldap.foo.com</string>
                                        </void>
                                        <void property="connectTimeout">
                                                <int>3000</int>
                                        </void>
                                </object>
                        </void>
                </void>
        </object>
</java>

Here is the list of top-level properties:

property Type/unit Description
interval miliseconds when the whole server pool is down, wait for this amount before trying again
searchBase string LDAP search base
webHooks object list of web hooks
countLimit integer retry count of connect attempts
connectTimeout miliseconds per server pool connect timeout
searchTimeout miliseconds per server pool search timeout
servers object list of LDAP servers

List of webHooks properties:

property Type/unit Description
URI string URI to post HTTP request to
content string the content of the request

Server properties:

property Type/unit Description
name string URL of the server
connectTimeout milisecond per server connect timeout

The handy thing about the setup is that it can be placed right underneath the pluginStack definition, so that it can be shared by all LDAP plugins.

LdapUserPlugin

Uses the information stored in the request by the UserPlugin and performs LDAP lookup to construct LdapUser object and stores the object as session attribute (to provide caching in order to limit the queries to LDAP servers). The other LDAP plugins can then use the DN and LDAP attributes stored in the object.

Properties:

Name Description
filter the LDAP filter to use when looking up the LDAP object. It is important to specify the filter so that it matches one LDAP object only. The filter can use attributes of the User object, namely its id and username.
attributes comma separated list of LDAP attributes to lookup and store in the LdapUser object
instance (optional, default empty) instance number of the plugin. This provides naming of the session attribute so that other LDAP plugins can reference particular LdapUser object (e.g. from certain server).
useDN (optional, default false) whether to treat the username property of the User object as DN when looking up the LDAP object. This is handy in case the Identity server supplies this, e.g. useful when using OSSOHeaderDecoder.

Example configuration

            <void method="add">
                <object class="org.opengrok.indexer.authorization.AuthorizationPlugin">
                    <void property="name">
                        <string>opengrok.auth.plugin.LdapUserPlugin</string>
                    </void>
                    <void property="flag">
                        <string>REQUISITE</string>
                    </void>
                    <void property="setup">
                        <void method="put">
                            <string>filter</string>
                            <string>(&amp;(objectclass=person)(mail=%guid%)(uid=%username%))</string>
                        </void>
                        <void method="put">
                             <string>attributes</string>
                             <string>mail,uid</string>
                        </void>
                    </void>
                </object>
            </void>

LdapAttrPlugin

Performs a check of LDAP attribute against a whitelist. It relies on the LdapUser object to be present in the session because it uses the DN of the user to perform the lookup (to avoid unnecessary traversal of LDAP directory tree).

Example configuration

    <void method="add">                                                         
        <object class="org.opengrok.indexer.authorization.AuthorizationPlugin"> 
            <void property="name">                                              
                <string>opengrok.auth.plugin.LdapAttrPlugin</string>            
            </void>                                                             
            <void property="flag">                                              
                <string>SUFFICIENT</string>                                     
            </void>                                                             
            <void property="setup">                                             
                <void method="put">                                             
                    <string>attribute</string>                                  
                    <string>mail</string>                                       
                </void>                                                         
                <void method="put">                                             
                    <string>file</string>                                       
                    <string>/opengrok/auth/config/whitelists/foo-whitelist-mail.txt</string>
                </void>                                                         
            </void>                                                             
        </object>                                                               
    </void>

LdapFilterPlugin

Uses LDAP filter to check whether the request should be allowed. If no object is found, the request is denied.

Properties:

Name Description
filter the LDAP filter to use when looking up the LDAP object. The filter can use attributes acquired by the LdapUserPlugin and UserPlugin.
instance (optional, default empty) which instance of LdapUser object to use

Example configuration

In the following example notice these things:

  • per plugin LDAP server configuration is used
  • the filter expands the uid attribute from the LdapUser object
  • some special characters need to be escaped in the filter string (& but not *)
    <void method="add">                                                         
        <object class="org.opengrok.indexer.authorization.AuthorizationPlugin"> 
            <void property="name">                                              
                <string>opengrok.auth.plugin.LdapFilterPlugin</string>          
            </void>                                                             
            <void property="flag">                                              
                <string>REQUIRED</string>                                       
            </void>                                                             
            <void property="setup">                                             
                <void method="put">                                             
                    <string>configuration</string>                              
                    <string>/opengrok/auth/config/ldap-plugin-config-foo.xml</string>
                </void>                                                         
                <void method="put">                                             
                    <string>filter</string>                                     
                    <string>(&amp;(objectclass=posixGroup)(cn=src*)(memberUid=%uid%))</string>
                </void>                                                         
            </void>                                                             
        </object>                                                               
    </void>