简体   繁体   English

如何检查用户是否属于Java中的某些AD组

[英]How to check if user belongs to certain AD group in java

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. 我知道这肯定是一个非常简单的问题,但是我是java的新手,很难找到需要的确切代码。 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. 我需要做的是从Windows获取当前登录的用户名,并检查该用户是否属于需要在某些配置文件中定义的特定AD用户组。 It is very easy to do in C#, but I have no idea how to do it in JAVA. 在C#中很容易做到,但是我不知道如何在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. 在c#中,我会将安全组放入App.Config中,然后放入应用设置中,然后可以获取当前登录用户的Windows身份,然后遍历用户所属的所有组并与所需的组进行匹配。 I need to do exactly the same in java 我需要在Java中做完全一样的事情

If you only care about the currently logged on Windows user (ie, 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. 如果您只关心当前登录的Windows用户(即,您的Java程序将在Windows上运行),并且不介意使用JNA ,则可以使用platform.jarAdvapi32Util#getCurrentUserGroups()提供的函数来获取用户所属的组。

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. 这还利用了以下事实:用户登录时Windows会在所有组(包括包含用户所属的其他组的组)中缓存用户成员身份。


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. 这里的需求似乎是非特定的,并且这开始转向可能不太适合SO的领域,但是我还是会尝试一下。

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. 如果要在连接到要验证的同一域的基于Windows的服务器上运行,则应查看Waffle ,它提供了一个Servlet,Spring Security过滤器,JAAS插件以及其他几种方式可以实现Windows集成身份验证,该身份验证使用本机Windows方法加载Windows身份和关联的Active Directory组。 This will provide you with the experience most similar to using IIS and WIA with a .NET framework application. 这将为您提供与将IIS和WIA与.NET Framework应用程序结合使用最相似的体验。 The down-side to this is that the server needs to be run on a Windows system. 不利的一面是服务器需要在Windows系统上运行。

Unfortunately, running in a non-Windows environment is going to require more setup and configuration. 不幸的是,在非Windows环境中运行将需要更多的设置和配置。 The most integrated solution is likely Spring Security which has a Kerberos extension capable of providing SPNEGO (Windows Integrated Authentication). 集成度最高的解决方案可能是Spring Security,它具有能够提供SPNEGO(Windows集成身份验证) 的Kerberos扩展 The link above has the details (I believe they are still current) on what is necessary to get the Kerberos filter up and running. 上面的链接提供了有关启动和运行Kerberos筛选器所需的详细信息(我相信它们仍然是最新的)。 To access the group information, you would need to change the userDetailsService value in the example security.xml file. 要访问组信息,您需要在示例security.xml文件中更改userDetailsService值。 The easiest thing to do here would be to provide an appropriately configured LdapUserDetailsService as the object here. 此处最简单的操作是在此处提供适当配置的LdapUserDetailsS​​ervice作为对象。 I'm not all that experienced with Spring, but it looks like the configuration would be something like (this is missing the contextSource ). 我对Spring的经验还不是很丰富,但是看起来配置看起来像这样(这缺少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. 这应该为您提供一个经过Kerberos身份验证的用户及其关联的组。

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. 如果不接受Spring Security,则可以尝试使用Shiro纯Java SPNEGO过滤器来滚动自己的版本,但是要显示该示例,基本上需要编写程序。

I hope this helps. 我希望这有帮助。 Once you've decided on an approach, it's probably appropriate to address more specific questions as SO-type questions. 一旦确定了方法,就可以将更具体的问题作为SO型问题解决。

You can get all the groups without JNA like this: 您可以像这样不使用JNA来获得所有组:

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. 显然,这仅在Windows上有效,甚至不鼓励在Windows上使用com.sun。*软件包。 See this for the explanation of the result. 对结果的解释。

This can be done through the Java SE APIs without using the com.sun.* packages directly. 可以通过Java SE API完成此操作,而无需直接使用com.sun。*软件包。 Use Java Authentication and Authorization Service (JAAS) (javax.security.auth.* and javax.security.auth.login.*) to access this information. 使用Java身份验证和授权服务(JAAS) (javax.security.auth。*和javax.security.auth.login。*)来访问此信息。 Create a JAAS config file with the following entry: 使用以下条目创建一个JAAS配置文件

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

Save that entry as sampleapp_jaas.config . 将该条目另存为sampleapp_jaas.config Next set the system property so Java will look for the config file. 接下来,设置系统属性,以便Java查找配置文件。

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

Note that the double equals has special meaning. 请注意,double equals具有特殊含义。 See the com.sun.security.auth.login.ConfigFile for details on the load order. 有关加载顺序的详细信息,请参见com.sun.security.auth.login.ConfigFile

Then create LoginContext that will look for the entry in the JAAS config. 然后创建LoginContext,它将在JAAS配置中查找条目。 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. 使用此设置,Java将使用com.sun.security.auth.module.NTSystem类获取信息,但是您的任何代码都不会硬连线到非标准API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM