February 9, 2015

LDAP Authentication in Tomcat 7

Introduction Tomcat Configuration

Before starting we need to understand the Tomcat configuration (Context) hierarchy. Tomcat configuration can be placed in three places.

    - In $CATALINA_BASE/conf/server.xml.

    - In application /META-INF/context.xml.
    
    - In $CATALINA_BASE/conf/[enginename]/[hostname]/[appname].xml. The default 
    enginename is Catalina. The default hostname is localhost. Which resolves 
    above path to $CATALINA_BASE/conf/Catalina/localhost/[appname].xml.

    [http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context]

The recommended alternative is the last, externally the application, but not intrusive the Tomcat server.

This seperation makes also automated configuration more easily:

  1. One package with standardised Tomcat configuration.
  2. And another package for each application and their seperated configuration.

Next step is to do the actual Authentication configuration which is done by a Realm component.

    "A Catalina container (Engine, Host, or Context) may contain no more than ONE Realm element" 

    [http://tomcat.apache.org/tomcat-7.0-doc/config/realm.html#Introduction]

So a Realm is kind of like a singletone, but it also have scoope, depending where we place it.

    - Inside an <Engine> element - This Realm will be shared across ALL web 
    applications on ALL virtual hosts, UNLESS it is overridden by a Realm element 
    nested inside a subordinate <Host> or <Context> element.
    
    - Inside a <Host> element - This Realm will be shared across ALL web 
    applications for THIS virtual host, UNLESS it is overridden by a Realm element 
    nested inside a subordinate <Context> element.
    
    - Inside a <Context> element - This Realm will be used ONLY for THIS web application.

    [http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html#Configuring_a_Realm]

Configuration

Tomcat comes with several authentication modules (Realm) out of the boxes. Here we will use the LDAP authentication module org.apache.catalina.realm.JNDIRealm.

JNDI Directory Realm - org.apache.catalina.realm.JNDIRealm

JNDIRealm

$ vi $CATALINA_BASE/conf/Catalina/localhost/example-ldap.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Realm className="org.apache.catalina.realm.JNDIRealm" 
        connectionURL="ldap://ldap.magnuskkarlsson.com:389"
        userPattern="uid={0},ou=People,dc=magnuskkarlsson,dc=com" 
        roleBase="ou=Group,dc=magnuskkarlsson,dc=com"
        roleName="cn" roleSearch="(memberUid={1})" />
</Context>

users.ldif

dn: uid=magkar,ou=People,dc=magnuskkarlsson,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: top
uid: magkar
givenName: Magnus
initials: K
sn: Karlsson
cn: Magnus K Karlsson
mail: magnus.k.karlsson@msc.se
uidNumber: 500
gidNumber: 500
homeDirectory: /home/student
userPassword: {crypt}$6$TgMwYtfv6Z0C8Peo$H7p8XjUYuBIspHgTmbo2KKSusssqFuBJFi58uRIcFVsObQJr72RHmBEq9Qz8JcBuA0tCbKvmDawxbQzz112/y0
shadowLastChange: 16467
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash

dn: cn=magkar,ou=Group,dc=magnuskkarlsson,dc=com
objectClass: top
objectClass: posixGroup
cn: magkar
userPassword: {crypt}x
gidNumber: 500

dn: cn=tomcat,ou=Group,dc=magnuskkarlsson,dc=com
objectClass: top
objectClass: posixGroup
cn: tomcat
userPassword: {crypt}x
gidNumber: 501
memberUid: magkar

Test

To test this we create a simple web application.

example-ldap.war/index.jsp

<html>
<body>
<p>Remote User : <%= request.getRemoteUser()  %></p>
</body>
</html>

example-ldap.war/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0" metadata-complete="true">

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>tomcat</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>Example LDAP Authentication</realm-name>
    </login-config>

    <security-role>
        <role-name>tomcat</role-name>
    </security-role>
</web-app>

No comments: