Class LdapAccessControl

  • All Implemented Interfaces:
    UserAccessControl

    public class LdapAccessControl
    extends Object
    implements UserAccessControl
    The LdapAccessControl class is a reference implementation of the UserAccessControl interface. This class only performs user authorization (authZ) and not user authentication (authN). This class implements an authZ model in a similar style as the Role Based Access Control (RBAC) model and the Attribute Based Access Control (ABAC) model. However, this pedagogical implementation is much simpler and limited than the two formal models.

    Usage examples and semantics can be found in the javadoc of the interface that this class implements (UserAccessControl).

    The LdapAccessControl implementation makes calls to an LDAP server (e.g. Microsoft's Active Directory (AD) server) when performing a lookup to determine if a user has one or more attributes defined. The LDAP queries are based on LDAP search/filter criteria(s) defined at the time an instance of this class is placed into service. An instance of this class is considered to be in service after invoking the init method.

    In the SPNEGO Library, the SpnegoHttpFilter class is the mechanism that performs user authentication (authN) whilst the LdapAccessControl class is the default mechanism that performs user authorization (authZ). This default can be replaced by any class that implement the UserAccessControl interface. To change the default, specify the new class in the SPNEGO Library's filter definition section of the web.xml file.

    Authorization (authZ) is an optional feature of the SPNEGO Library. The SPNEGO Library provides an interface, SpnegoAccessControl, to applications that require authZ capability. Applications can check a user's authZ by calling methods defined in the SpnegoAccessControl interface.

    The LdapAccessControl class is configured within the same web.xml filter section as the SpnegoHttpFilter class. The configuration is specified by adding additional filter parameters to the SpnegoHttpFilter filter definition.

    Example web.xml Configuration:

     <filter>
         <filter-name>SpnegoHttpFilter</filter-name>
         <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
         
         <!-- spnego http filter params (authN) -->
         ... existing authN params here just as before ...
         
         <!-- spnego http filter params (authZ) -->     
         <init-param>
             <param-name>spnego.authz.class</param-name>
             <param-value>net.sourceforge.spnego.LdapAccessControl</param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.ldap.url</param-name>
             <param-value>ldap://athena.local:389</param-value>
         </init-param>
         
         <!-- an example user-defined resource label -->
         <init-param>
             <param-name>spnego.authz.resource.name.1</param-name>
             <param-value>admin-buttons</param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.resource.access.1</param-name>
             <param-value>Biz. Analyst,Los Angeles,IT Group</param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.resource.type.1</param-name>
             <param-value>has</param-value>
         </init-param>
         
         <!-- CDATA required since specifying filter(s) in web.xml (vs. a policy file) -->
         <!-- also notice the %1$s and the %2$s tokens (always required) -->
         <init-param>
             <param-name>spnego.authz.ldap.filter.1</param-name>
              <param-value><![CDATA[(&(sAMAccountName=%1$s)(memberOf:1.2.840.113556.1.4.1941:=CN=%2$s,OU=Groups,OU=Los Angeles,DC=athena,DC=local))]]></param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.ldap.filter.2</param-name>
             <param-value><![CDATA[(&(sAMAccountType=805306368)(sAMAccountName=%1$s)(&(sAMAccountType=805306368)(department=%2$s)))]]></param-value>
         </init-param>
     </filter>
     

    As an alternative option, the spnego.authz.ldap.filter.[i] parameters and the spnego.authz.resource.[name|access|type].[i] parameters may be specified in a policy file.

    Example Policy File Configuration:

     <filter>
         <filter-name>SpnegoHttpFilter</filter-name>
         <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
         
         <!-- spnego http filter params (authN) -->
         ... existing authN params here just as before ...
         
         <!-- spnego http filter params (authZ) -->     
         <init-param>
             <param-name>spnego.authz.class</param-name>
             <param-value>net.sourceforge.spnego.LdapAccessControl</param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.ldap.url</param-name>
             <param-value>ldap://athena.local:389</param-value>
         </init-param>
         <init-param>
             <param-name>spnego.authz.policy.file</param-name>
             <param-value>C:/Apache Software Foundation/Tomcat 7.0/conf/spnego.policy</param-value>
         </init-param>
     </filter>
     
    Policy file contents:
     # an example user-defined resource label
     spnego.authz.resource.name.1=admin-buttons
     spnego.authz.resource.access.1=Biz. Analyst,Los Angeles,IT Group
     spnego.authz.resource.type.1=has
     
     # do NOT use CDATA like in the web.xml file
     # the %1$s and the %2$s tokens are always required
     spnego.authz.ldap.filter.1=(&(sAMAccountName=%1$s)(memberOf:1.2.840.113556.1.4.1941:=CN=%2$s,OU=Groups,OU=Los Angeles,DC=athena,DC=local))
     spnego.authz.ldap.filter.2=(&(sAMAccountType=805306368)(sAMAccountName=%1$s)(&(sAMAccountType=805306368)(department=%2$s)))
     

    For more information on how a web application/service can leverage access controls or to view some usage examples, please read the javadoc of the SpnegoAccessControl interface and the javadoc of the UserAccessControl interface.

    Also, take a look at the reference docs for a complete list of configuration parameters.

    Finally, to see a working example and instructions, take a look at the authZ for standalone apps example and the enable authZ with LDAP guide.

    Author:
    Darwin V. Felix
    • Constructor Summary

      Constructors 
      Constructor Description
      LdapAccessControl()
      Default constructor.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      boolean anyAccess​(String username, String... resources)
      Checks to see if the given user has at least one of the passed-in user-defined resource labels.
      boolean anyRole​(String username, String... attributes)
      Checks to see if the given user has at least one of the passed-in attributes.
      void destroy()
      Used for clean-up when usage of the object is no longer needed and no other method calls will be made on this instance.
      UserInfo getUserInfo​(String username)
      Returns a user info object if specified in web.xml or the spnego.policy file.
      boolean hasAccess​(String username, String resource)
      Checks to see if the passed-in user has access to the user-defined resource label.
      boolean hasAccess​(String username, String resourceX, String... resourceYs)
      Checks to see if the given user has the first resource label AND has at least one of the passed-in resource labels.
      boolean hasRole​(String username, String attribute)
      Checks to see if the given user has the passed-in attribute.
      boolean hasRole​(String username, String attributeX, String... attributeYs)
      Checks to see if the given user has the first attribute AND has at least one of the passed-in attributes.
      void init​(Properties props)
      Method is used for initialization prior to use/calling any other method.
    • Constructor Detail

      • LdapAccessControl

        public LdapAccessControl()
        Default constructor.
    • Method Detail

      • destroy

        public void destroy()
        Description copied from interface: UserAccessControl
        Used for clean-up when usage of the object is no longer needed and no other method calls will be made on this instance.

        Calling this method is an indication that no other method calls will be called on this instance. If method calls must resume on this instance, the init method MUST be called before this instance can be placed back into service.

        If this method has been called and a reference to the instance is maintained, the init method must be called again to re-initialize the object's instance variables.

        Specified by:
        destroy in interface UserAccessControl
      • anyRole

        public boolean anyRole​(String username,
                               String... attributes)
        Description copied from interface: UserAccessControl
        Checks to see if the given user has at least one of the passed-in attributes.
         String[] attributes = new String[] {"Developer", "Los Angeles", "Manager"};
         
         if (accessControl.anyRole("dfelix", attributes)) {
             // will be in here if dfelix has at least one matching attribute
         }
         
        Specified by:
        anyRole in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        attributes - e.g. Team Lead, IT, Developer
        Returns:
        true if the user has at least one of the passed-in roles/features
      • hasRole

        public boolean hasRole​(String username,
                               String attribute)
        Description copied from interface: UserAccessControl
        Checks to see if the given user has the passed-in attribute.
         String attribute = "Los Angeles";
         
         if (accessControl.hasRole("dfelix", attribute)) {
             // will be in here if dfelix has that one attribute
         }
         
        Specified by:
        hasRole in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        attribute - e.g. IT
        Returns:
        true if the user has the passed-in role/attribute
      • hasRole

        public boolean hasRole​(String username,
                               String attributeX,
                               String... attributeYs)
        Description copied from interface: UserAccessControl
        Checks to see if the given user has the first attribute AND has at least one of the passed-in attributes.
         String attributeX = "Los Angeles";
         String[] attributeYs = new String[] {"Developer", "Manager"};
         
         if (accessControl.hasRole("dfelix", attributeX, attributeYs)) {
             // will be in here if dfelix has attributeX 
             // AND has at least one of the attributeYs.
         }
         
        Specified by:
        hasRole in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        attributeX - e.g. Information Technology
        attributeYs - e.g. Team Lead, IT-Architecture-DL
        Returns:
        true if user has featureX AND at least one the featureYs
      • anyAccess

        public boolean anyAccess​(String username,
                                 String... resources)
        Description copied from interface: UserAccessControl
        Checks to see if the given user has at least one of the passed-in user-defined resource labels.
         if (accessControl.anyAccess("dfelix", "admin-links", "buttons-for-ops")) {
             // will be in here if dfelix has at least one matching resource
         }
         
        Specified by:
        anyAccess in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        resources - e.g. admin-links, ops-buttons
        Returns:
        true if the user has at least one of the passed-in user-defined resource labels
      • hasAccess

        public boolean hasAccess​(String username,
                                 String resource)
        Description copied from interface: UserAccessControl
        Checks to see if the passed-in user has access to the user-defined resource label.
         UserAccessControl accessControl = ...;
         boolean editAndAdminBtns = false;
         
         if (accessControl.hasAccess("dfelix", "admin-buttons")) {
             editAndAdminBtns = true;
         }
         
        Specified by:
        hasAccess in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        resource - e.g. admin-buttons
        Returns:
        true if user has access to the user-defined resource labels
      • hasAccess

        public boolean hasAccess​(String username,
                                 String resourceX,
                                 String... resourceYs)
        Description copied from interface: UserAccessControl
        Checks to see if the given user has the first resource label AND has at least one of the passed-in resource labels.
         String resourceX = "phone-list";
         String[] resourceYs = new String[] {"staff-directory", "procedure-manual"};
         
         if (accessControl.hasAccess("dfelix", resourceX, resourceYs)) {
             // will be in here if dfelix has resourceX 
             // AND has at least one of the resourceYs.
         }
         
        Specified by:
        hasAccess in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        resourceX - e.g. phone-list
        resourceYs - e.g. staff-directory, procedure-manual, emergency-contact-list
        Returns:
        true if user has resourceX AND at least one the resourceYs
      • getUserInfo

        public UserInfo getUserInfo​(String username)
        Returns a user info object if specified in web.xml or the spnego.policy file.

        Case-sensitive

        web.xml Example:

             ...
             <init-param>
                 <param-name>spnego.authz.user.info</param-name>
                 <param-value>mail,department,memberOf,displayName</param-value>
             </init-param>
             <init-param>
                 <param-name>spnego.authz.ldap.user.filter</param-name>
                 <param-value><![CDATA[(&(sAMAccountType=805306368)(sAMAccountName=%1$s))]]></param-value>
             </init-param>
             ...
         

        spnego.policy File Example:

         ...
         # case-sensitive
         spnego.authz.user.info=mail,department,memberOf,displayName
         spnego.authz.ldap.user.filter=(&(sAMAccountType=805306368)(sAMAccountName=%1$s))
         ...
         

        Specified by:
        getUserInfo in interface UserAccessControl
        Parameters:
        username - e.g. dfelix
        Returns:
        UserInfo object with the specified ldap attributes
      • init

        public void init​(Properties props)
        Description copied from interface: UserAccessControl
        Method is used for initialization prior to use/calling any other method.

        Calling this method is an indication that this instance is in service/active and any method can be called at anytime for the purpose of servicing a request.

        If this method has been called and a reference to the instance is maintained, this method should not be called again unless the destroy method is called first.

        Specified by:
        init in interface UserAccessControl