我知道这一定是一个非常简单的问题,但我是java的新手,并且很难找到我需要的确切代码。我需要做的是从Windows获取当前登录的用户名,并检查该用户是否属于需要在某个配置文件中定义的特定AD用户组。在C#中很容易做到,但我不知道如何在JAVA中做到这一点。示例代码会很棒。在c#中,我将安全组放入App.Config进入应用程序设置,然后我可以获取当前登录用户的Windows标识,然后遍历用户所属的所有组并与所需的匹配。我需要在java中完全相同
答案 0 :(得分:4)
如果您只关心当前登录的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环境中运行需要更多的设置和配置。最集成的解决方案可能是具有a Kerberos extension能够提供SPNEGO(Windows集成身份验证)的Spring Security。上面的链接有关于启动和运行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和the pure-Java SPNEGO filter来编辑自己的版本,但是显示一个示例就需要基本上编写程序。
我希望这会有所帮助。一旦你决定采用某种方法,就可以将更具体的问题作为SO型问题来解决。
答案 1 :(得分:2)
你可以在没有JNA的情况下获得所有这样的组:
String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
显然这只适用于Windows,甚至在Windows上也不鼓励使用com.sun。*软件包。有关结果的说明,请参阅this。
答案 2 :(得分:0)
这可以通过Java SE API完成,而无需直接使用com.sun。*包。使用Java Authentication and Authorization Service (JAAS)(javax.security.auth。*和javax.security.auth.login。*)来访问此信息。使用以下条目创建JAAS config file:
sampleApp {
com.sun.security.auth.module.NTLoginModule required debug=false;
};
将该条目另存为sampleapp_jaas.config
。接下来设置系统属性,以便Java查找配置文件。
-Djava.security.auth.login.config==sampleapp_jaas.config
请注意,double equals具有特殊含义。有关加载顺序的详细信息,请参阅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。