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

后端 未结 3 627
Happy的楠姐
Happy的楠姐 2021-01-21 17:46

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

相关标签:
3条回答
  • 2021-01-21 17:53

    This can be done through the Java SE APIs without using the com.sun.* packages directly. Use Java Authentication and Authorization Service (JAAS) (javax.security.auth.* and javax.security.auth.login.*) to access this information. Create a JAAS config file with the following entry:

    sampleApp {
        com.sun.security.auth.module.NTLoginModule required debug=false;
    };
    

    Save that entry as sampleapp_jaas.config. Next set the system property so Java will look for the config file.

    -Djava.security.auth.login.config==sampleapp_jaas.config
    

    Note that the double equals has special meaning. See the com.sun.security.auth.login.ConfigFile for details on the load order.

    Then create LoginContext that will look for the entry in the JAAS config. Call login to populate the subject then access principals which represent the user groups.

    LoginContext l = new LoginContext("sampleApp");
    l.login();
    try {
        Subject s = l.getSubject();
        for (Principal p : s.getPrincipals()) {
            System.out.println(p);
        }
    } finally {
        l.logout();
    }
    

    Using this setup, Java will use the com.sun.security.auth.module.NTSystem class to get the information but none of your code will be hardwired to the non-standard APIs.

    0 讨论(0)
  • 2021-01-21 18:01

    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.

    0 讨论(0)
  • 2021-01-21 18:14

    You can get all the groups without JNA like this:

    String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
    

    Obviously this will work only on Windows, and even on Windows is the use of com.sun.* packages discouraged. See this for the explanation of the result.

    0 讨论(0)
提交回复
热议问题