2

我知道这一定是一个非常简单的问题,但我是 java 新手,很难获得我需要的确切代码。我需要做的是从 Windows 获取当前登录的用户名,并检查该用户是否属于需要在某个配置文件中定义的特定 AD 用户组。在 C# 中很容易做到,但我不知道如何在 JAVA 中做到这一点。示例代码会很棒。在 c# 中,我会将安全组放入 App.Config 到应用程序设置中,然后我可以获取当前登录用户的 Windows 身份,然后遍历用户所属的所有组并与所需的匹配。我需要在java中做同样的事情

4

3 回答 3

3

如果您只关心当前登录的 Windows 用户(即,您的 Java 程序将在 Windows 上运行)并且不介意使用JNA,您可以使用 中提供的函数platform.jarAdvapi32Util#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文件中的值。此处最简单的做法是提供适当配置的LdapUserDetailsS​​ervice作为此处的对象。我对 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 类型的问题来解决可能是合适的。

于 2012-06-13T12:27:48.833 回答
2

您可以像这样获得没有 JNA 的所有组:

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

显然,这只适用于 Windows,甚至在 Windows 上也不鼓励使用 com.sun.* 包。有关结果的说明,请参见this

于 2013-02-28T15:18:08.507 回答
0

这可以通过 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。

于 2013-10-16T17:40:45.430 回答