[java] Authenticating against Active Directory with Java on Linux

I have a simple task of authenticating against Active Directory using Java. Just verifying credentials and nothing else. Let's say my domain is "fun.xyz.tld", OU path is unknown, and username/password is testu/testp.

I know there's a few Java libraries out there that simplify this task, but I wasn't successful at implementing them. Most examples that I've found addressed LDAP in general, not specifically Active Directory. Issuing LDAP request means sending an OU path in it, which I don't have. Also, the application that issues LDAP request should be already bound to Active Directory in order to access it... Insecure, since the credentials would have to be stored someplace discoverable. I would like a test bind with test credentials, if possible - this would mean that account is valid.

Last, if possible, is there a way to make such authentication mechanism encrypted? I know that AD uses Kerberos, but not sure if Java's LDAP methods do.

Does anyone has an example of working code? Thanks.

This question is related to java authentication active-directory ldap

The answer is


Are you just verifying credentials? In that case you could just do plain kerberos and not bother with LDAP.


I just finished a project that uses AD and Java. We used Spring ldapTemplate.

AD is LDAP compliant (almost), I don't think you will have any issues with the task you have. I mean the fact that it is AD or any other LDAP server it doesn't matter if you want just to connect.

I would take a look at: Spring LDAP

They have examples too.

As for encryption, we used SSL connection (so it was LDAPS). AD had to be configured on a SSL port/protocol.

But first of all, make sure you can properly connect to your AD via an LDAP IDE. I use Apache Directory Studio, it is really cool, and it is written in Java. That is all I needed. For testing purposes you could also install Apache Directory Server


I recommend you to look at the adbroker package of the oVirt project. It uses Spring-Ldap and the Krb5 JAAS Login module (with GSSAPI) in order to authenticate using Kerberos against Ldap servers (Active-Directory, ipa, rhds, Tivoli-DS). Look for the code at engine\backend\manager\modules\bll\src\main\java\org\ovirt\engine\core\bll\adbroker

You can use git to clone the repository or browse using the gerrit link


I just finished a project that uses AD and Java. We used Spring ldapTemplate.

AD is LDAP compliant (almost), I don't think you will have any issues with the task you have. I mean the fact that it is AD or any other LDAP server it doesn't matter if you want just to connect.

I would take a look at: Spring LDAP

They have examples too.

As for encryption, we used SSL connection (so it was LDAPS). AD had to be configured on a SSL port/protocol.

But first of all, make sure you can properly connect to your AD via an LDAP IDE. I use Apache Directory Studio, it is really cool, and it is written in Java. That is all I needed. For testing purposes you could also install Apache Directory Server


There are 3 authentication protocols that can be used to perform authentication between Java and Active Directory on Linux or any other platform (and these are not just specific to HTTP services):

  1. Kerberos - Kerberos provides Single Sign-On (SSO) and delegation but web servers also need SPNEGO support to accept SSO through IE.

  2. NTLM - NTLM supports SSO through IE (and other browsers if they are properly configured).

  3. LDAP - An LDAP bind can be used to simply validate an account name and password.

There's also something called "ADFS" which provides SSO for websites using SAML that calls into the Windows SSP so in practice it's basically a roundabout way of using one of the other above protocols.

Each protocol has it's advantages but as a rule of thumb, for maximum compatibility you should generally try to "do as Windows does". So what does Windows do?

First, authentication between two Windows machines favors Kerberos because servers do not need to communicate with the DC and clients can cache Kerberos tickets which reduces load on the DCs (and because Kerberos supports delegation).

But if the authenticating parties do not both have domain accounts or if the client cannot communicate with the DC, NTLM is required. So Kerberos and NTLM are not mutually exclusive and NTLM is not obsoleted by Kerberos. In fact in some ways NTLM is better than Kerberos. Note that when mentioning Kerberos and NTLM in the same breath I have to also mention SPENGO and Integrated Windows Authentication (IWA). IWA is a simple term that basically means Kerberos or NTLM or SPNEGO to negotiate Kerberos or NTLM.

Using an LDAP bind as a way to validate credentials is not efficient and requires SSL. But until recently implementing Kerberos and NTLM have been difficult so using LDAP as a make-shift authentication service has persisted. But at this point it should generally be avoided. LDAP is a directory of information and not an authentication service. Use it for it's intended purpose.

So how do you implement Kerberos or NTLM in Java and in the context of web applications in particular?

There are a number of big companies like Quest Software and Centrify that have solutions that specifically mention Java. I can't really comment on these as they are company-wide "identity management solutions" so, from looking the marketing spin on their website, it's hard to tell exactly what protocols are being used and how. You would need to contact them for the details.

Implementing Kerberos in Java is not terribly hard as the standard Java libraries support Kerberos through the org.ietf.gssapi classes. However, until recently there's been a major hurdle - IE doesn't send raw Kerberos tokens, it sends SPNEGO tokens. But with Java 6, SPNEGO has been implemented. In theory you should be able to write some GSSAPI code that can authenticate IE clients. But I haven't tried it. The Sun implementation of Kerberos has been a comedy of errors over the years so based on Sun's track record in this area I wouldn't make any promises about their SPENGO implementation until you have that bird in hand.

For NTLM, there is a Free OSS project called JCIFS that has an NTLM HTTP authentication Servlet Filter. However it uses a man-in-the-middle method to validate the credentials with an SMB server that does not work with NTLMv2 (which is slowly becoming a required domain security policy). For that reason and others, the HTTP Filter part of JCIFS is scheduled to be removed. Note that there are number of spin-offs that use JCIFS to implement the same technique. So if you see other projects that claim to support NTLM SSO, check the fine print.

The only correct way to validate NTLM credentials with Active Directory is using the NetrLogonSamLogon DCERPC call over NETLOGON with Secure Channel. Does such a thing exist in Java? Yes. Here it is:

http://www.ioplex.com/jespa.html

Jespa is a 100% Java NTLM implementation that supports NTLMv2, NTLMv1, full integrity and confidentiality options and the aforementioned NETLOGON credential validation. And it includes an HTTP SSO Filter, a JAAS LoginModule, HTTP client, SASL client and server (with JNDI binding), generic "security provider" for creating custom NTLM services and more.

Mike


Are you just verifying credentials? In that case you could just do plain kerberos and not bother with LDAP.



I recommend you to look at the adbroker package of the oVirt project. It uses Spring-Ldap and the Krb5 JAAS Login module (with GSSAPI) in order to authenticate using Kerberos against Ldap servers (Active-Directory, ipa, rhds, Tivoli-DS). Look for the code at engine\backend\manager\modules\bll\src\main\java\org\ovirt\engine\core\bll\adbroker

You can use git to clone the repository or browse using the gerrit link



There are 3 authentication protocols that can be used to perform authentication between Java and Active Directory on Linux or any other platform (and these are not just specific to HTTP services):

  1. Kerberos - Kerberos provides Single Sign-On (SSO) and delegation but web servers also need SPNEGO support to accept SSO through IE.

  2. NTLM - NTLM supports SSO through IE (and other browsers if they are properly configured).

  3. LDAP - An LDAP bind can be used to simply validate an account name and password.

There's also something called "ADFS" which provides SSO for websites using SAML that calls into the Windows SSP so in practice it's basically a roundabout way of using one of the other above protocols.

Each protocol has it's advantages but as a rule of thumb, for maximum compatibility you should generally try to "do as Windows does". So what does Windows do?

First, authentication between two Windows machines favors Kerberos because servers do not need to communicate with the DC and clients can cache Kerberos tickets which reduces load on the DCs (and because Kerberos supports delegation).

But if the authenticating parties do not both have domain accounts or if the client cannot communicate with the DC, NTLM is required. So Kerberos and NTLM are not mutually exclusive and NTLM is not obsoleted by Kerberos. In fact in some ways NTLM is better than Kerberos. Note that when mentioning Kerberos and NTLM in the same breath I have to also mention SPENGO and Integrated Windows Authentication (IWA). IWA is a simple term that basically means Kerberos or NTLM or SPNEGO to negotiate Kerberos or NTLM.

Using an LDAP bind as a way to validate credentials is not efficient and requires SSL. But until recently implementing Kerberos and NTLM have been difficult so using LDAP as a make-shift authentication service has persisted. But at this point it should generally be avoided. LDAP is a directory of information and not an authentication service. Use it for it's intended purpose.

So how do you implement Kerberos or NTLM in Java and in the context of web applications in particular?

There are a number of big companies like Quest Software and Centrify that have solutions that specifically mention Java. I can't really comment on these as they are company-wide "identity management solutions" so, from looking the marketing spin on their website, it's hard to tell exactly what protocols are being used and how. You would need to contact them for the details.

Implementing Kerberos in Java is not terribly hard as the standard Java libraries support Kerberos through the org.ietf.gssapi classes. However, until recently there's been a major hurdle - IE doesn't send raw Kerberos tokens, it sends SPNEGO tokens. But with Java 6, SPNEGO has been implemented. In theory you should be able to write some GSSAPI code that can authenticate IE clients. But I haven't tried it. The Sun implementation of Kerberos has been a comedy of errors over the years so based on Sun's track record in this area I wouldn't make any promises about their SPENGO implementation until you have that bird in hand.

For NTLM, there is a Free OSS project called JCIFS that has an NTLM HTTP authentication Servlet Filter. However it uses a man-in-the-middle method to validate the credentials with an SMB server that does not work with NTLMv2 (which is slowly becoming a required domain security policy). For that reason and others, the HTTP Filter part of JCIFS is scheduled to be removed. Note that there are number of spin-offs that use JCIFS to implement the same technique. So if you see other projects that claim to support NTLM SSO, check the fine print.

The only correct way to validate NTLM credentials with Active Directory is using the NetrLogonSamLogon DCERPC call over NETLOGON with Secure Channel. Does such a thing exist in Java? Yes. Here it is:

http://www.ioplex.com/jespa.html

Jespa is a 100% Java NTLM implementation that supports NTLMv2, NTLMv1, full integrity and confidentiality options and the aforementioned NETLOGON credential validation. And it includes an HTTP SSO Filter, a JAAS LoginModule, HTTP client, SASL client and server (with JNDI binding), generic "security provider" for creating custom NTLM services and more.

Mike


As ioplex and others have said, there are many options. To authenticate using LDAP (and the Novell LDAP API), I have used something like:


LDAPConnection connection = new LDAPConnection( new LDAPJSSEStartTLSFactory() );
connection.connect(hostname, port);
connection.startTLS();
connection.bind(LDAPConnection.LDAP_V3, username+"@"+domain, password.getBytes());

As a "special feature", Active Directory allows LDAP binds against "user@domain" without using the distinguished name of the account. This code uses StartTLS to enable TLS encryption on the connection; the other alternative is LDAP over SSL, which is not supported by my AD servers.

The real trick is in locating the server and host; the official way is to use a DNS SRV (service) record lookup to locate a bundle of candidate hosts, then do a UDP-based LDAP "ping" (in a particular Microsoft format) to locate the correct server. If you are interested, I've posted some blog articles about my journey of adventure and discovery in that area.

If you want to do Kerberos-based username/password authentication, you are looking at another kettle of fish; it is doable with the Java GSS-API code, although I am not sure it performs the final step to validate the authentication. (The code doing the validation can contact the AD server to check the username and password, which results in a ticket granting ticket for the user, but to ensure the AD server is not being impersonated, it also needs to try to get a ticket for the user to itself, which is somewhat more complicated.)

If you want to do Kerberos-based single sign-on, assuming your users are authenticated to the domain, you can do that as well with the Java GSS-API code. I would post a code sample, but I still need to turn my hideous prototype into something fit for human eyes. Check out some code from SpringSource for some inspiration.

If you are looking for NTLM (which I was given to understand is less secure) or something else, well, good luck.


Are you just verifying credentials? In that case you could just do plain kerberos and not bother with LDAP.



If all you want to do is authenticate against AD using Kerberos, then a simple http://spnego.sourceforge.net/HelloKDC.java program should do it.

Take a look at the project's "pre-flight" documentation which talks about the HelloKDC.java program.


I just finished a project that uses AD and Java. We used Spring ldapTemplate.

AD is LDAP compliant (almost), I don't think you will have any issues with the task you have. I mean the fact that it is AD or any other LDAP server it doesn't matter if you want just to connect.

I would take a look at: Spring LDAP

They have examples too.

As for encryption, we used SSL connection (so it was LDAPS). AD had to be configured on a SSL port/protocol.

But first of all, make sure you can properly connect to your AD via an LDAP IDE. I use Apache Directory Studio, it is really cool, and it is written in Java. That is all I needed. For testing purposes you could also install Apache Directory Server


Are you just verifying credentials? In that case you could just do plain kerberos and not bother with LDAP.


As ioplex and others have said, there are many options. To authenticate using LDAP (and the Novell LDAP API), I have used something like:


LDAPConnection connection = new LDAPConnection( new LDAPJSSEStartTLSFactory() );
connection.connect(hostname, port);
connection.startTLS();
connection.bind(LDAPConnection.LDAP_V3, username+"@"+domain, password.getBytes());

As a "special feature", Active Directory allows LDAP binds against "user@domain" without using the distinguished name of the account. This code uses StartTLS to enable TLS encryption on the connection; the other alternative is LDAP over SSL, which is not supported by my AD servers.

The real trick is in locating the server and host; the official way is to use a DNS SRV (service) record lookup to locate a bundle of candidate hosts, then do a UDP-based LDAP "ping" (in a particular Microsoft format) to locate the correct server. If you are interested, I've posted some blog articles about my journey of adventure and discovery in that area.

If you want to do Kerberos-based username/password authentication, you are looking at another kettle of fish; it is doable with the Java GSS-API code, although I am not sure it performs the final step to validate the authentication. (The code doing the validation can contact the AD server to check the username and password, which results in a ticket granting ticket for the user, but to ensure the AD server is not being impersonated, it also needs to try to get a ticket for the user to itself, which is somewhat more complicated.)

If you want to do Kerberos-based single sign-on, assuming your users are authenticated to the domain, you can do that as well with the Java GSS-API code. I would post a code sample, but I still need to turn my hideous prototype into something fit for human eyes. Check out some code from SpringSource for some inspiration.

If you are looking for NTLM (which I was given to understand is less secure) or something else, well, good luck.


There are 3 authentication protocols that can be used to perform authentication between Java and Active Directory on Linux or any other platform (and these are not just specific to HTTP services):

  1. Kerberos - Kerberos provides Single Sign-On (SSO) and delegation but web servers also need SPNEGO support to accept SSO through IE.

  2. NTLM - NTLM supports SSO through IE (and other browsers if they are properly configured).

  3. LDAP - An LDAP bind can be used to simply validate an account name and password.

There's also something called "ADFS" which provides SSO for websites using SAML that calls into the Windows SSP so in practice it's basically a roundabout way of using one of the other above protocols.

Each protocol has it's advantages but as a rule of thumb, for maximum compatibility you should generally try to "do as Windows does". So what does Windows do?

First, authentication between two Windows machines favors Kerberos because servers do not need to communicate with the DC and clients can cache Kerberos tickets which reduces load on the DCs (and because Kerberos supports delegation).

But if the authenticating parties do not both have domain accounts or if the client cannot communicate with the DC, NTLM is required. So Kerberos and NTLM are not mutually exclusive and NTLM is not obsoleted by Kerberos. In fact in some ways NTLM is better than Kerberos. Note that when mentioning Kerberos and NTLM in the same breath I have to also mention SPENGO and Integrated Windows Authentication (IWA). IWA is a simple term that basically means Kerberos or NTLM or SPNEGO to negotiate Kerberos or NTLM.

Using an LDAP bind as a way to validate credentials is not efficient and requires SSL. But until recently implementing Kerberos and NTLM have been difficult so using LDAP as a make-shift authentication service has persisted. But at this point it should generally be avoided. LDAP is a directory of information and not an authentication service. Use it for it's intended purpose.

So how do you implement Kerberos or NTLM in Java and in the context of web applications in particular?

There are a number of big companies like Quest Software and Centrify that have solutions that specifically mention Java. I can't really comment on these as they are company-wide "identity management solutions" so, from looking the marketing spin on their website, it's hard to tell exactly what protocols are being used and how. You would need to contact them for the details.

Implementing Kerberos in Java is not terribly hard as the standard Java libraries support Kerberos through the org.ietf.gssapi classes. However, until recently there's been a major hurdle - IE doesn't send raw Kerberos tokens, it sends SPNEGO tokens. But with Java 6, SPNEGO has been implemented. In theory you should be able to write some GSSAPI code that can authenticate IE clients. But I haven't tried it. The Sun implementation of Kerberos has been a comedy of errors over the years so based on Sun's track record in this area I wouldn't make any promises about their SPENGO implementation until you have that bird in hand.

For NTLM, there is a Free OSS project called JCIFS that has an NTLM HTTP authentication Servlet Filter. However it uses a man-in-the-middle method to validate the credentials with an SMB server that does not work with NTLMv2 (which is slowly becoming a required domain security policy). For that reason and others, the HTTP Filter part of JCIFS is scheduled to be removed. Note that there are number of spin-offs that use JCIFS to implement the same technique. So if you see other projects that claim to support NTLM SSO, check the fine print.

The only correct way to validate NTLM credentials with Active Directory is using the NetrLogonSamLogon DCERPC call over NETLOGON with Secure Channel. Does such a thing exist in Java? Yes. Here it is:

http://www.ioplex.com/jespa.html

Jespa is a 100% Java NTLM implementation that supports NTLMv2, NTLMv1, full integrity and confidentiality options and the aforementioned NETLOGON credential validation. And it includes an HTTP SSO Filter, a JAAS LoginModule, HTTP client, SASL client and server (with JNDI binding), generic "security provider" for creating custom NTLM services and more.

Mike


I just finished a project that uses AD and Java. We used Spring ldapTemplate.

AD is LDAP compliant (almost), I don't think you will have any issues with the task you have. I mean the fact that it is AD or any other LDAP server it doesn't matter if you want just to connect.

I would take a look at: Spring LDAP

They have examples too.

As for encryption, we used SSL connection (so it was LDAPS). AD had to be configured on a SSL port/protocol.

But first of all, make sure you can properly connect to your AD via an LDAP IDE. I use Apache Directory Studio, it is really cool, and it is written in Java. That is all I needed. For testing purposes you could also install Apache Directory Server


If all you want to do is authenticate against AD using Kerberos, then a simple http://spnego.sourceforge.net/HelloKDC.java program should do it.

Take a look at the project's "pre-flight" documentation which talks about the HelloKDC.java program.


ldap authentication without SSL is not safe and anyone can view user credential because ldap client transfer usernamae and password during ldap bind operation So Always use ldaps protocol. source: Ldap authentication Active directory in Java Spring Security with Example


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to authentication

Set cookies for cross origin requests How Spring Security Filter Chain works What are the main differences between JWT and OAuth authentication? http post - how to send Authorization header? ASP.NET Core Web API Authentication Token based authentication in Web API without any user interface Custom Authentication in ASP.Net-Core Basic Authentication Using JavaScript Adding ASP.NET MVC5 Identity Authentication to an existing project LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1

Examples related to active-directory

Powershell: A positional parameter cannot be found that accepts argument "xxx" How to switch to another domain and get-aduser How can I verify if an AD account is locked? Powershell script to see currently logged in users (domain and machine) + status (active, idle, away) Querying Windows Active Directory server using ldapsearch from command line How to list AD group membership for AD users using input list? Import-Module : The specified module 'activedirectory' was not loaded because no valid module file was found in any module directory What are CN, OU, DC in an LDAP search? PowerShell script to return members of multiple security groups How do I get specific properties with Get-AdUser

Examples related to ldap

LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1 Querying Windows Active Directory server using ldapsearch from command line What are CN, OU, DC in an LDAP search? LDAP server which is my base dn Easy way to test an LDAP User's Credentials LDAP filter for blank (empty) attribute LDAP Authentication using Java How to create and add users to a group in Jenkins for authentication? Query to list all users of a certain group using wildcards in LDAP search filters/queries