在Karaf(7)中使用Kerberos身份验证连接到Ldap服务器时出现问题。我无法使用System.setProperty(" java.security.auth.login.config"," /path/jaas.conf")通过jaas.conf文件加载kerberos内容。 。因此,我尝试了一种程序化的方法。问题是它破坏了想要使用Krb5LoginModule的其他模块/应用程序的配置,即当我设置配置时,先前的配置被销毁。有没有办法避免这种情况?
一些代码
package com.company.one;
import com.sun.security.auth.module.Krb5LoginModule;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class TestLdap {
public void testLdap() {
Configuration jaasConfig = createJaasConfig();
Configuration.setConfiguration(jaasConfig);
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.setProperty(Context.PROVIDER_URL, "ldap://myldap:389");
props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
props.setProperty(Context.SECURITY_AUTHENTICATION, "GSSAPI");
final String filter = "(&(objectClass=employee)(uid=someId))";
LdapContext ctx = null;
try {
ctx = new InitialLdapContext(props, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum = ctx.search("dc=company,dc=se", filter, getSimpleSearchControls());
while (namingEnum.hasMore()) {
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
if (attrs.get("uid") != null) {
log.info("Attrs = {}", attrs);
}
}
namingEnum.close();
} catch (Exception e) {
e.printStackTrace();
log.info(e.getMessage());
}
}
private static Configuration createJaasConfig() {
// Create entry options.
Map<String, Object> options = new HashMap<String, Object>();
options.put("debug", "true");
options.put("doNotPrompt", "true");
options.put("storeKey", "true");
options.put("principal", "nameofprincipal");
options.put("useKeyTab", "true");
options.put("keyTab", "/local/foo/conf/mykeytab");
// Create entries.
AppConfigurationEntry[] entries = {
new AppConfigurationEntry(
Krb5LoginModule.class.getCanonicalName(),
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options)
};
// Create configuration.
return new Configuration() {
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
return entries;
}
};
}
}
答案 0 :(得分:0)
您可以在蓝图中制作jaas-config并进行部署:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<jaas:config name="XX.COM" rank="1">
<jaas:module name="myname" className="com.sun.security.auth.module.Krb5LoginModule" flags="required">
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
principal=myprincipal@xx.com
useKeyTab=true
keyTab=/etc/krb5.keytab-test
storeKey=true
doNotPrompt=true
debug=true
refreshKrb5Config=true
</jaas:module>
</jaas:config>
</blueprint>
然后你可以制作类似的代码:
private void getPerson(Person person, String filter) throws NamingException {
final Hashtable gssapiEnv = createEnv();
final CallbackHandler callbackHandler = callbacks -> {
for (Callback callback : callbacks) {
if (callback instanceof RealmCallback) {
((RealmCallback) callback).setText("XX.COM");
}
}
};
final LoginContext lc;
try {
lc = new LoginContext("XX.COM", callbackHandler);
lc.login();
final LdapContext ctx = Subject.doAs(lc.getSubject(), (PrivilegedAction<LdapContext>) () -> {
InitialLdapContext result = null;
try {
result = new InitialLdapContext(gssapiEnv, null);
} catch (NamingException ex) {
ex.printStackTrace();
}
return result;
});
final NamingEnumeration<?> namingEnum = ctx.search("dc=xx,dc=com", filter, getSimpleSearchControls());
while (namingEnum.hasMore()) {
readPerson(ctx, person, namingEnum);
}
namingEnum.close();
} catch (LoginException e) {
e.printStackTrace();
}
}
private Hashtable createEnv() {
final Hashtable<String, String> env = new Hashtable<>(11);
System.setProperty("java.security.krb5.kdc", "kerberos.xx.com");
System.setProperty("java.security.krb5.realm","XX.COM");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://myldap.xx.com:389");
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
env.put(Context.SECURITY_PRINCIPAL, "XX.COM");
return env;
}