【问题标题】:How can you store credentials in a JNDI lookup?如何在 JNDI 查找中存储凭据?
【发布时间】:2012-10-17 18:19:25
【问题描述】:

我有一个包含多个 properties 文件的应用程序,我很好奇将这些 username/password/server-url-to-login-to 组合存储在 JNDI 查找中而不是这个明文文件中是否更容易一个.jar。

有几个问题:

  1. 能否使用 JNDI 存储不是数据库的凭据?
  2. 如何配置新的 JNDI 资源来存储这些属性?
  3. 您将如何从资源中检索这些属性?

我阅读的大部分文档是如何为数据库连接设置 JNDI,而就我的使用而言,我没有连接到 任何 数据库,而是使用不同身份验证的不同类型的 Web 服务方案(请求消息中的 SOAP 用户/密码、HTTP Basic、标头、SSL 等)。

【问题讨论】:

标签: glassfish jndi


【解决方案1】:

您的问题的答案:

  1. 能否使用 JNDI 存储不是数据库的凭据?

是的。

  1. 如何配置新的 JNDI 资源来存储这些属性?

如果您使用的是 Glassfish 2,则必须创建自定义 PropertiesObjectFactory 类来处理 java.util.PorpertiesJNDI 属性。

例如PropertiesObjectFactory 类可能如下所示:

public class PropertiesObjectFactory implements Serializable, ObjectFactory {

    public static final String FILE_PROPERTY_NAME = "org.glassfish.resources.custom.factory.PropertiesFactory.fileName";

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
            throws Exception {
        Reference ref = (Reference) obj;
        Enumeration<RefAddr> refAddrs = ref.getAll();

        String fileName = null;
        Properties fileProperties = new Properties();
        Properties properties = new Properties();

        while (refAddrs.hasMoreElements()) {
            RefAddr addr = refAddrs.nextElement();
            String type = addr.getType();
            String value = (String) addr.getContent();

            if (type.equalsIgnoreCase(FILE_PROPERTY_NAME)) {
                fileName = value;
            } else {
                properties.put(type, value);
            }
        }

        if (fileName != null) {
            File file = new File(fileName);
            if (!file.isAbsolute()) {
                file = new File(System.getProperty("com.sun.aas.installRoot") + File.separator + fileName);
            }
            try {
                if (file.exists()) {
                    try {
                        FileInputStream fis = new FileInputStream(file);
                        if (fileName.toUpperCase().endsWith("XML")) {
                            fileProperties.loadFromXML(fis);
                        } else {
                            fileProperties.load(fis);
                        }
                    } catch (IOException ioe) {
                        throw new IOException("IO Exception during properties load : " + file.getAbsolutePath());
                    }
                } else {
                    throw new FileNotFoundException("File not found : " + file.getAbsolutePath());
                }
            } catch (FileNotFoundException fnfe) {
                throw new FileNotFoundException("File not found : " + file.getAbsolutePath());
            }
        }
        fileProperties.putAll(properties);
        return fileProperties;
    }
}

制作该类的 jar,将其添加到 glassfish 全局类路径中。它将是:/glassfish/domains/domain1/lib,然后您可以在 JNDI 属性配置中将其指定为工厂类。

Glassfish 3 已经有属性工厂类。设置为:org.glassfish.resources.custom.factory.PropertiesFactory

打开 glassfish 管理控制台并导航到:资源 -> JNDI -> 自定义资源,单击“新建”,提供 JNDI 名称,例如:jndi/credentials,选择资源类型java.util.Properties,指定工厂类:@ 987654331@,然后单击“添加属性”,指定名称,例如:testUsernameName 和值列testUsernameValue。单击确定,就这样,您已经配置了JNDI 资源。您可以在其中添加任意数量的属性:jndi/credentials 资源。

创建资源后不要忘记重启应用服务器。

  1. 您将如何从资源中检索这些属性?
public Properties getProperties(String jndiName) {
    Properties properties = null;
    try {
        InitialContext context = new InitialContext();
        properties = (Properties) context.lookup(jndiName);
        context.close();
    } catch (NamingException e) {
        LOGGER.error("Naming error occurred while initializing properties from JNDI.", e);
        return null;
    }
    return properties;
}

获取属性的示例:

String username = someInstance.getProperties("jndi/credentials").getProperty("testUsernameName"); 

您的username 将是:testUsernameValue

当您在应用程序中调用此方法时,请提供您在应用程序服务器中配置的 JNDI 名称:jndi/credentials。如果您在部署描述符中映射了资源,则必须使用:java:comp/env/jndi/credentials

如果你想用Spring做同样的事情:

<jee:jndi-lookup id="credentials"
                 jndi-name="jndi/credentials"/>

我希望就是这样。希望这会有所帮助。

【讨论】:

  • 我知道这是旧的,但我希望你仍然知道答案,因为我试图在 glassfish4.1 上重新创建它。我应该将哪些 .jars 用于上下文和属性?或者它们是否包含在预定义的包中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 2020-07-22
  • 1970-01-01
  • 2016-05-05
  • 2016-07-28
  • 1970-01-01
相关资源
最近更新 更多