Requirements to Use AD Bridge with Active Directory in SSO

  • Root access to the Linux computer
  • The Linux computer is joined to Active Directory with Likewise AD Bridge 6.1 later
  • Administrative access to the Active Directory for creating a service account if one does not exist
  • The Linux computer is running Apache Tomcat Server version 5.5 or later
  • The server is running JRE 1.5.0 or higher
  • The AD Bridge application integration package is installed

 

Configuring Java application servers is a complex procedure. Before you deploy your configuration to a production web server, implement and test it in a test environment. Before you change your application server’s configuration, read and understand the documentation that accompanies the application server. Before you change a file, make a backup copy.

Components

The following Likewise components relevant to Apache integration are installed at /opt/pbis/{lib, lib64}.

Component Name Description
lwjplatform.jar

AD Bridge Platform Library

lwservlets.jar

AD Bridgeauthentication modules, including Servlet Filter and JAAS Module.

wtomcat.jar

AD Bridge authentication modules specific to implementing the Tomcat authentication valve.

This component is not needed if you use the authentication filter described in this document.

jna.jar Java Native Access Library patched for UCS-2 support.
commons-logging- 1.1.1.jar, log4j- 1.2.16.jar Logging facilities
commons-codec- 1.4.jar Base64 and other encoding routines
commons-net-2.2.jar Network utilities

Install the Authentication Components

The components from the integration package must be installed. Typically, an Apache Tomcat installation uses the following environment variables:

Environment Variable Value
CATALINA_HOME

Example: /usr/share/tomcat8

CATALINA_BASE

Example: /var/lib/tomcat8

To integrate your web application with the Likewise servlet filter you must install the following components in ${CATALINA_HOME}/webapps/<web application>/web-inf/lib:

  • lwservlets.jar
  • lwjplatform.jar
  • jna.jar
  • commons-logging-1.1.1.jar
  • log4j-1.2.16.jar
  • commons-codec-1.4.jar
  • commons-net-2.2.jar

Symbolic links can be created to these jar files from the target directory.

Generate Kerberos Keytab File

The Kerberos keytab file is necessary to authenticate incoming requests. It contains an encrypted, local copy of the host’s key. It is important to protect the file with proper file access permissions. The file must be readable by the user or group under which the Apache Tomcat server is running, typically tomcat on most Linux systems. No other user should be able to read or modify the file.

To generate the keytab file:

  • Find the server name of the web site that will require authentication. You can use the server name from Active Directory.
  • You need to know the fully qualified name of the domain to which the Linux system is joined.
  • You need to decide where to save the generated keytab file.

The steps below use a sample Apache user account name named tomcat, a sample server name of myserver, a sample full domain name of MYDOMAIN.COM, and a sample Kerberos keytab file named /etc/krb5_myserver.keytab. You must substitute the correct names from your system and configuration.

  1. Select a user in Active Directory for the application server. If you create a new user, make sure to set the password for the account to never expire. Also, make sure Use DES Encryption types for this account is not checked in the user account properties in Active Directory. In this example, we are using the user: MYDOMAIN\tomcat.
  2. Generate keytab entry on your Windows domain controller for the default HTTP service principal:
# ktpass /out c:\krb5_myserver.keytab /pType KRB5_NT_PRINCIPAL /crypto RC4- HMAC-NT /princ HTTP/myserver.mydomain.com@MYDOMAIN.COM /mapuser  tomcat@MYDOMAIN.COM /mapop set /pass password

If using Windows Server 2003, and prompting for password via /pass *, the domain controller may store an incorrect password preventing login.

  1. Copy the file to the target Linux machine and change the group ownership of the keytab file: # chown tomcat:tomcat /etc/krb5_myserver.keytab.
  2. Set appropriate file permissions of the keytab file:
# chgrp tomcat /etc/krb5.keytab
# chmod g+r /etc/krb5.keytab

If you choose not to create a separate keytab but rather merge the generated data with default keytab file (typically /etc/krb5.keytab), you must provide read access to the file to the local tomcat user.

  1. Set the KRB5_KTNAME environment variable of the Tomcat process. This can be set in the beginning of the Tomcat initialization script at /etc/init.d/tomcat: export KRB5_KTNAME=FILE:/etc/krb5_myserver.keytab.

Change the Application Web Descriptor

Now you need to add filter and filter-mapping sections to the web descriptor of your web application (web-inf/web.xml). It must be done for every web application you are planning to protect with the Likewise servlet filter. The example below demonstrates how your configuration may look (remember to replace MYDOMAIN with your short domain name):

<filter>
  <filter-name>LikewiseAuth</filter-name>
  <filter-class>com.likewise.auth.filter.spnego.LikewiseNegotiateFilter</filter-class>
  <init-param> 
     <param-name>deny-role</param-name>
     <param-value>MYDOMAIN\guests</param-value>
  </init-param> 
  <init-param>
     <param-name>allow-role</param-name>
     <param-value>MYDOMAIN\domain^users</param-value>
  </init-param>
  <init-param>
     <param-name>remote-address-accept-filter</param-name>
     <param-value>10.100.0.0/24</param-value>
  </init-param>
  <init-param> 
     <param-name>remote-address-accept-filter</param-name>
     <param-value>10.100.1.0,255.255.255.0</param-value> 
  </init-param>
</filter>

<filter-mapping>
   <filter-name>LikewiseAuth</filter-name> 
   <url-pattern>/*</url-pattern>
</filter-mapping>

The above configuration ensures that only members of the MYDOMAIN\domain^users group can access the web pages from this application. Users who belong to the MYDOMAIN\guests group will be denied access. It is possible to configure multiple deny and allow roles. The user is checked for membership in the deny roles before being checked in the allow roles.

Role names are case-sensitive. Always use upper-case register for the domain name component and lower-case for the group names. Use ^ in place of white spaces in group names.

The remote-address-accept-filter configuration parameter can be used to specify IP addresses in the CIDR format. For example, 10.100.0.0/24. It can also be in the form of IP Address with Subnet mask. For example, 10.100.0.0,255.255.255.0. If at least one remote-address-accept-filter parameter is specified, the servlet performs authentication only of the requests whose remote IP Address is in the range of the permitted addresses. The filter first tries to obtain the IP address of the client from X-Forwarded-For HTTP header. The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer. If the header is not set the filter gets the client IP address directly from the TCP/IP socket. If the client IP address is not in the configured range of accepted IP addresses the filter passes the HTTP request to the web application unauthenticated. As a result, the user principal object will not be set in the HTTP session. The access control logic of the web application must decide how to treat unauthenticated HTTP requests. It may choose to reject access, or redirect the request to a different URL, or allow restricted access to the application resources.

Edit the Java policy file

The JVM running the application server puts certain restrictions on the type of operations the web application code is allowed to perform. The authentication filter must be able to read configuration files, and load and execute native libraries in the /opt/likewise directory. For this reason, the Java policy file needs to be extended. This step can be skipped if the Java security manager is disabled in your application server configuration. Below is a sample policy file for Tomcat6. This file can be saved as /var/lib/tomcat6/conf/policy.d/20sample.policy.

Consult your application server documentation to find the location of the policy file. Note that name myapp below must be substituted with the real name of your web application. You will also need to adjust the ${catalina.base} variable appropriately since it is only available in Tomcat:

grant codeBase "file:${catalina.base}/webapps/myapp/WEB-INF/lib/jna.jar" { 
   permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/myapp/WEB- INF/lib/lwjplatform.jar" {  
   permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/myapp/WEB- INF/lib/lwservlets.jar" {
   permission java.security.AllPermission;
};

grant codeBase "file:/opt/pbis/lib/-" { 
   permission java.security.AllPermission;
};

grant codeBase "file:/opt/pbis/lib64/-" { 
   permission java.security.AllPermission;
};

Protect Web Pages

You can protect access to resources of your web application either programmatically, or declaratively. It is also possible to use a combination of both methods.

Programmatic security provide for the following APIs, which you can use in JSPs and servlets of your web application:

  • isUserInRole(): This method determines if the currently authenticated user belongs to a specified role. Roles correspond to groups in Active Directory the Linux computer is joined to. For example, if an HTTP request has been successfully authenticated for user valjean who is a member of MYDOMAIN\domain^users group, the following expression would return true: request.isUserInRole("MYDOMAIN\domain^users"). If no user is currently authenticated (for example, if authorization failed or if isUserInRole is called from an unrestricted page and the user has not yet accessed a restricted page), isUserInRole returns false.
  • getRemoteUser(): This method returns the name of the current user. For example, if the client has successfully logged in as user valjean, request.getRemoteUser() would return valjean. If no user is currently authenticated (for example, if authorization failed or if isUserInRole is called from an unrestricted page and the user has not yet accessed a restricted page), getRemoteUser returns null.
  • getUserPrincipal(): This method returns the current username wrapped inside a java.security.Principal object. If no user is currently authenticated, getUserPrincipal returns null. The Principal object contains little information beyond the username (available with the getName method). Likewise extends the standard Principal class to provide access to additional principal information through such methods as getUserId(), getPrimaryGroupId(), getHomeDirectory(), getSecurityIdentifier(), getGecos(), getShell(), getDistinguishedName(), getPrincipalName(), isLocalUser(). This information can be accessed after casting the Principal instance to LikewiseUser class:
Principal p = request.getUserPrincipal();
if(p != null) {
  LikewiseUser lwUser = (LikewiseUser) p;
}

Declarative security model enables you to describe access control logic directly in the web.xml file. For instance, the following web.xml sample illustrates how to protect all the web pages in your application so they are accessible only to users who belong to the MYDOMAIN\domain^users group.

<security-role>
<role-name>MYDOMAIN\domain^users</role-name>
</security-role>
<security-constraint>
  <display-name>Likewise Security Constraint</display-name>
  <web-resource-collection>
     <web-resource-name>Protected Area</web-resource-name>
     <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
     <role-name>MYDOMAIN\domain^users</role-name>
  </auth-constraint>
</security-constraint>

Configure the JAAS Module

AD Bridge Enterprise uses Kerberos5 JAAS module for user authentication. This section explains how to set up the JAAS module to complete the integration of your application server.

  1. Create a file named /opt/p<is/share/config/jaas.policy and add the following lines to it:
grant Principal * * {
permission java.security.AllPermission "/*";
};
  1. Create a file name /opt/p<is/share/config/login.conf and add the following lines to it:
Jaas {
com.likewise.auth.jaas.LikewiseLoginModule sufficient;
};
  1. Add the following java parameters to the command line of the script that starts your application server:
-Djava.security.auth.login.config=/opt/p<is/share/config/login.conf
-Djava.security.auth.policy=/opt/p<is/share/config/jaas.policy

Restart the Tomcat Server

Restart your application server. For example:

/etc/init.d/tomcat restart