我知道这一定是一个非常简单的问题,但我是 java 新手,很难获得我需要的确切代码。我需要做的是从 Windows 获取当前登录的用户名,并检查该用户是否属于需要在某个配置文件中定义的特定 AD 用户组。在 C# 中很容易做到,但我不知道如何在 JAVA 中做到这一点。示例代码会很棒。在 c# 中,我会将安全组放入 App.Config 到应用程序设置中,然后我可以获取当前登录用户的 Windows 身份,然后遍历用户所属的所有组并与所需的匹配。我需要在java中做同样的事情
3 回答
如果您只关心当前登录的 Windows 用户(即,您的 Java 程序将在 Windows 上运行)并且不介意使用JNA,您可以使用 中提供的函数platform.jar
来Advapi32Util#getCurrentUserGroups()
获取用户所属的组.
例如:
import com.sun.jna.platform.win32.Advapi32Util;
for (Advapi32Util.Account account : Advapi32Util.getCurrentUserGroups()) {
System.out.println(account.fqn);
}
这还利用了当用户登录时 Windows 缓存所有组(包括包含用户所属的其他组的组)中的用户成员身份这一事实。
这里的要求似乎有点不具体,这开始转向可能不太适合 SO 的领域,但无论如何我都会试一试。
最终,您的系统将在哪里运行决定了设置的难度。如果您要在基于 Windows 的服务器上运行,该服务器连接到您正在验证的同一个域,那么您应该查看Waffle,它提供了一个 servlet、一个 Spring Security 过滤器、一个 JAAS 插件和其他一些您可以使用的方式可以实现 Windows 集成身份验证,该身份验证使用本机 Windows 方法加载 Windows 身份和关联的 Active Directory 组。这将为您提供最类似于将 IIS 和 WIA 与 .NET 框架应用程序一起使用的体验。这样做的缺点是服务器需要在 Windows 系统上运行。
不幸的是,在非 Windows 环境中运行将需要更多的设置和配置。最集成的解决方案可能是 Spring Security,它具有能够提供 SPNEGO(Windows 集成身份验证)的 Kerberos 扩展。上面的链接包含有关启动和运行 Kerberos 过滤器所需的详细信息(我相信它们仍然是最新的)。要访问组信息,您需要更改userDetailsService
示例security.xml
文件中的值。此处最简单的做法是提供适当配置的LdapUserDetailsService作为此处的对象。我对 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>
这应该让您获得一个经过 Kerberos 身份验证的用户及其关联的组。
如果 Spring Security 不可接受,您可以尝试使用Shiro和纯 Java SPNEGO 过滤器来滚动您自己的版本,但展示一个示例需要基本上编写一个程序。
我希望这有帮助。一旦你决定了一种方法,将更具体的问题作为 SO 类型的问题来解决可能是合适的。
您可以像这样获得没有 JNA 的所有组:
String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
显然,这只适用于 Windows,甚至在 Windows 上也不鼓励使用 com.sun.* 包。有关结果的说明,请参见this。
这可以通过 Java SE API 完成,而无需直接使用 com.sun.* 包。使用Java 身份验证和授权服务 (JAAS)(javax.security.auth.* 和 javax.security.auth.login.*)访问此信息。使用以下条目创建JAAS 配置文件:
sampleApp {
com.sun.security.auth.module.NTLoginModule required debug=false;
};
将该条目另存为sampleapp_jaas.config
. 接下来设置系统属性,以便 Java 将查找配置文件。
-Djava.security.auth.login.config==sampleapp_jaas.config
请注意,双等号具有特殊含义。有关加载顺序的详细信息,请参见com.sun.security.auth.login.ConfigFile。
然后创建将在 JAAS 配置中查找条目的 LoginContext。调用 login 填充主题,然后访问代表用户组的主体。
LoginContext l = new LoginContext("sampleApp");
l.login();
try {
Subject s = l.getSubject();
for (Principal p : s.getPrincipals()) {
System.out.println(p);
}
} finally {
l.logout();
}
使用此设置,Java 将使用 com.sun.security.auth.module.NTSystem 类来获取信息,但您的任何代码都不会被硬连接到非标准 API。