Java – How to check if user belongs to certain AD group in java

active-directoryjavawindows

I know it must be a very easy question, but I am new to java and find it hard to get exact code that I need. What I need to be able to do is to get currently logged in username from Windows and check whether this user belongs to the specific AD user group which needs to be defined in some config file. It is very easy to do in C#, but I have no idea how to do it in JAVA. Sample code would be great. In c# I would put security group into App.Config into app settings then I can grab Windows Identity of the currently logged in user and then iterate through all the groups user belongs to and match with desired. I need to do exactly the same in java

Best Answer

If you only care about the currently logged on Windows user (i.e., your Java program will be running on Windows) and don't mind using JNA, you can use the function supplied in platform.jar, Advapi32Util#getCurrentUserGroups() to get the groups that a user is a member of.

For example:

import com.sun.jna.platform.win32.Advapi32Util;

for (Advapi32Util.Account account : Advapi32Util.getCurrentUserGroups()) {
    System.out.println(account.fqn);
}

This also takes advantage of the fact that Windows caches the users membership in all groups (including groups containing other groups the user is a member of) when the user logs on.


The requirements here seem kind of non-specific and this is starting to veer into areas that are probably not a great fit for SO, but I'll give it a go anyway.

Ultimately, where your system is going to be run determines how difficult the setup is going to be. If you are going to be running on a Windows-based server connected to the same domain you are authenticating with, then you should look at Waffle, which provides a servlet, a Spring Security filter, a JAAS plugin and a few other ways that you can implement Windows Integrated Authentication which uses native Windows methods to load the Windows identity and associated Active Directory groups. This will provide you with the experience most similar to using IIS and WIA with a .NET framework application. The down-side to this is that the server needs to be run on a Windows system.

Unfortunately, running in a non-Windows environment is going to require more setup and configuration. The most integrated solution is likely Spring Security which has a Kerberos extension capable of providing SPNEGO (Windows Integrated Authentication). The link above has the details (I believe they are still current) on what is necessary to get the Kerberos filter up and running. To access the group information, you would need to change the userDetailsService value in the example security.xml file. The easiest thing to do here would be to provide an appropriately configured LdapUserDetailsService as the object here. I'm not all that experienced with Spring, but it looks like the configuration would be something like (this is missing the contextSource).

<bean id="adUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <constructor-arg value="dc=domain,dc=com"/>
    <constructor-arg value="(sAMAccountName={0})"/>
    <constructor-arg ref="contextSource" />
</bean>

<bean id="adAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
    <constructor-arg ref="contextSource"/>
    <constructor-arg value="dc=domain,dc=com" />
    <property name="groupSearchFilter" value="(member={0})"/>
    <property name="rolePrefix" value="ROLE_"/>
    <property name="searchSubtree" value="true"/>
    <property name="convertToUpperCase" value="true"/>
</bean>

<bean id="userDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
    <constructor-arg ref="adUserSearch"/>
    <constructor-arg ref="adAuthoritiesPopulator"/>
</bean>

This should get you a Kerberos authenticated user with their associated groups.

If Spring Security isn't acceptable, you could try rolling your own version of this using perhaps Shiro and the pure-Java SPNEGO filter, but showing an example of that would require basically writing a program.

I hope this helps. Once you've decided on an approach, it's probably appropriate to address more specific questions as SO-type questions.