簡體   English   中英

在Karaf中以編程方式設置JAAS配置(Kerberos)文件

[英]Setting JAAS Configuration (Kerberos) file programmatically in Karaf

在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;
            }
        };

    }
}

您可以在藍圖中制作一個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;
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM