JIRA NTLM/SSPI (Domain Trusted Login) using Apache HTTP Server

Atlassian does not support  and does not intend to provide the auto-login feature when the computer is in Windows Domain.

There are only 2 possible solutions:

  • Use crowd or any LDAP connector that makes it possible to login using Domain username and password (you have to actually provide the username and password, but it’s always the domain credentials)
  • Use ntlmauth4jira with jcifs plugin that might cause even more trouble (Starting from Windows Vista the default NTLM level is 5 and that means jcifs won’t work unless you change this value for each computer directly in windows registry files)

I’ve found a way how to use Apache Http Server NTLM authentication (mod_auth_sspi that works without any problem)  to authenticate in Jira running inside Apache Tomcat. The steps below are for Jira 3.x, but I succesfully tested it with only a minor changes for jira 4.1. Unfortunatelly, 4.x was not used as a production system so I can not guarantee the whole functionality in every aspect.

Steps

  1. Install Apache Http Server and Apache Tomcat
  2. Install mod_auth_sspi to your Apache Http Server
  3. Install proxy_ajp_module to your Apache Http Server (should be included by default)
  4. Setup Apache Http Server to forward requests to Apache Tomcat via AJP connector
  5. Install Jira
  6. Build the attached Jira plugin using Atlassian SDK or download the jar directly
  7. Configure the attached Jira plugin and change default Jira config in edit-webapp
  8. Start Jira

Install mod_auth_sspi

Open conf/httpd.conf file in your Apache Http Server installation and add or uncomment the following LoadModule lines:

############################################
# NTLM section BEGIN
LoadModule sspi_auth_module modules/mod_auth_sspi.so
# NTLM section END

Install proxy_ajp_module

Open conf/httpd.conf in your Apache Http Server installation and add or uncomment the following LoadModule lines:

############################################
# Proxy to local tomcats
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
ProxyErrorOverride on

Forward Apache Http Server requests to Apache Tomcat

Open conf/httpd.conf and add the lines below to the end (note, some installations of Http Server have separate file for this). Here you might ask why we need 3 separate locations. The first 2 are protected (SSPI/NTLM is required before the request is sent to Tomcat) and have higher priority. The last one is not protected and is for everything else (e.g. pictures, javascript etc) – this is because otherwise you won’t see the pictures in your email client when you receive jira email notification (there is no email client capable of SSPI authentication when body contains protected resources). If you don’t care about the pictures, just use the first Location and change /jira/browse to /jira.

<Location /jira/browse>
    ProxyPass           ajp://localhost:8009/jira/browse
    ProxyPassReverse    ajp://localhost:8009/jira/browse
    AuthName "JIRA - Enter your domain name and password"

    AuthType SSPI
    SSPIAuth On
    SSPIAuthoritative On
    SSPIOfferBasic On
    SSPIOmitDomain on

    Require valid-user
</Location>
<Location /jira/secure>
    ProxyPass           ajp://localhost:8009/jira/secure
    ProxyPassReverse    ajp://localhost:8009/jira/secure
    AuthName "JIRA - Enter your domain name and password"

    AuthType SSPI
    SSPIAuth On
    SSPIAuthoritative On
    SSPIOfferBasic On
    SSPIOmitDomain on

    Require valid-user
</Location>
<Location /jira>
    ProxyPass           ajp://localhost:8009/jira
    ProxyPassReverse    ajp://localhost:8009/jira
</Location>

Configure Apache Tomcat to receive AJP requests from Apache Http Server

Open conf/server.xml in Apache Tomcat directory and change the following:

  • disable HTTP connector (comment out Connector element with protocol HTTP/1.1)
  • enable AJP connector (uncomment Connector element with protocol AJP/1.3)
  • add URIEncoding=”UTF-8″ parameter to AJP Connector (this will fix the issue with accent/national characters)
  • add tomcatAuthentication=”false” parameter to AJP Connector (this will force Tomcat to read the username from AJP – the one provided by Http Server)
  • add address=”127.0.0.1″ parameter to AJP Connector (this will force Tomcat to listen only on localhost)

The AJP section should look like this:

    <Connector port="8009"
      address="127.0.0.1"
      protocol="AJP/1.3"
      redirectPort="8445"
      URIEncoding="UTF-8"
      connectionTimeout="5000"
      tomcatAuthentication="false" />

Configure the plugin and Jira

The plugin contains 3 different options to authenticate:

  • using Apache Http Server SSPI module
  • using jcifs library (copied from ntlmauth4jira plugin)
  • using jespa library (under development, not finished)

We’ll use the Apache Http Server Authentication. Http Server sends the authenticated user via AJP to Tomcat. The domain is not included (SSPIOmitDomain on), if the user is not connected to domain a basic authorization is offered (SSPIOfferBasic On). We have configured Tomcat to receive requests only from localhost and to use the username provided via AJP.

NOTE: If you enable remote access to Tomcat (AJP or HTTP) the username can be changed by the request sender and Jira can be tricked this way to think that the user is not who he/she claims to be!

Now we have to set a new Filter in Jira edit-webapp/web.xml to tell Jira that the user is succesfully authenticated if username is provided via AJP. The filter also checks if the user is in required group in LDAP (Active Directory in this case). Add the following lines just above trustedapps Filter:

   <filter>
    <filter-name>login_ntlm</filter-name>
    <filter-class>sk.lacike.ntlm.apache.jira.AJPLoginFilter</filter-class>
    <init-param>
     <param-name>configuration</param-name>
     <param-value>ntlm_ldap.properties</param-value>
    </init-param>
   </filter>

For jira 4.x you have to change the location, because the filters have been completely redesigned. I don’t exactly remember where it should be, I am pretty sure you’ll find out the correct position 🙂

ntlm_ldap.properties has to be copied into classes folder and the following lines have to be changed:

domains = [your-domain-here e.g. MYDOMAIN]
 stripDomain = true
 forceDomain = [your-domain-here e.g. MYDOMAIN]
 readonlyUser = true
 checkLDAP = false
domainController = [your-domain-controller-here e.g. domainserver.mydomain.local]
java.naming.security.authentication = simple
 java.naming.factory.initial = com.sun.jndi.ldap.LdapCtxFactory
 java.naming.referral = follow
java.naming.provider.url = [your-ldap-url-to-domain-controller e.g. ldap://domainserver.mydomain.local)
 searchBase = [your-search-base-where-users-are-stored, e.g. OU=employees,DC=mydomain,DC=local)
java.naming.security.principal = [full-dc-path-for-user, e.g. CN=atlassian,OU=systemaccounts,DC=mydomain,DC=local)
 java.naming.security.credentials = [dc-user-password, e.g. *****]
autoCreate = no
You can also set requiredJIRAGroup if you want authenticate only users with specific group.

The autoCreate=no readonlyUser=yes are usable when you have jira connected to LDAP via crowd – the user record is readonly for external jira user providers. If you don’t intend to use Crowd, just enable these options (set yo yes) and the user info will be retrieved from LDAP/DC automatically. Also, the user will be automatically created if it is found in LDAP.

If you have any trouble with jcifs (LDAP connectivity), just add the following lines:

jcifs.util.loglevel=3
jcifs.smb.client.useExtendedSecurity=true
jcifs.smb.lmCompatibility=3
jcifs.lmCompatibility=3

The last step is to copy the compiled plugin into edit-webapp/lib directory also with jcifs and jespa jars.

8 replies on “JIRA NTLM/SSPI (Domain Trusted Login) using Apache HTTP Server”

Our company provides a custom authenticator for Atlassian Jira and Confluence based on IOPlex Jespa component that is capable doing NTLMv2 authentication for these products without Apache. Get in touch if you need it.

That is great. I started to work also on JESPA authenticator (see my plugin), but I didn’t finish that. Mainly, because I didn’t have time and the jespa licence expired 🙂
I find my solution good basically because mod_auth_sspi uses standard windows libraries – there is no java cheating that might fail (like jcifs).

Could you, please, post here link to your plugin, I can’t find it on your page.

Thanks

Hi all,
its a pity that modul mod_auth_sspi is only for “windows” apache.

Well, you can always try to use mod_auth_ntlm (winbind) on linux. But anyway, if you have windows domain would that be such an issue to install one Http Server on windows machine and redirect the traffic to Linux Tomcats? I know, the security, but that can be solved too 😉
You can even try to use IIS on one of your existing machines and redirect to Tomcat (not that I would prefer MS solutions)

hi,

i configured the https in the application by using the self signed certificate. but while i try to access the site via IE . it was asking the credentials even if the person have an access. plz help

Hi,

I haven’t tried Apache’s proxy nor ajp modules in combination with https. Did you try it without https? Did you check the jira logs if the plugin is receiving the correct username (you should see a line containg username extraction even if it is null)?

One more thing: have you tried to access a simple static apache content using https and mod_auth_sspi? without proxying anything..