Wildfly - 在运行时设置数据源密码 [英] Wildfly - set datasource password at runtime

查看:22
本文介绍了Wildfly - 在运行时设置数据源密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Jboss wildfly 8.1 和 JPA Hibernate 开发服务器应用程序.问题是,必须在运行时加载 JPA 数据源信用(密码).当服务器启动时,它连接到一个加密存储,在那里它检索真实数据库的密码.之后,它应该建立与真实数据库的连接.

I am developing a server application using Jboss wildfly 8.1 and JPA Hibernate. The problem is, that the JPA datasource creditials have to be loaded at runtime (password). When the server starts, it connects to an encrypted storage where it retrieves password to real database. After that, it should establish connection to the real database.

我已经尝试了几件事:通过 JNDI 查找数据源并将其与实际 DS 重新绑定.通过 JNDI 查找 entityManagerFactory 并将其与自定义 EntityManager 重新绑定.

I tried several things already: Lookup the datasource through JNDI and rebind it with actual DS. Lookup the entityManagerFactory through JNDI and rebind it with custom EntityManager.

但这些都不起作用.你知道如何解决吗?

but none of these work. Do you have idea how to solve it?

我的配置:

持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0">
   <persistence-unit name="PERSISTENCE_UNIT" transaction-type="JTA">
      <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

      <jta-data-source>java:jboss/datasources/Datasource</jta-data-source>
      ...classes...

      <properties>
        <!-- Properties for Hibernate -->               
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
        <property name="hibernate.show_sql" value="false"/>
        <property name="hibernate.format_sql" value="false"></property>
        <property name="hibernate.connection.useUnicode" value="true"/>
        <property name="hibernate.connection.characterEncoding" value="UTF-8"/>
        <property name="hibernate.connection.charSet" value="UTF-8"/>
        <property name="org.hibernate.flushMode" value="commit" /> <!-- THIS ONE IS IMPORTANT -->

        <property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactory"/>
        <property name="jboss.entity.manager.jndi.name" value="java:/Manager1"/>
      </properties>      
   </persistence-unit>
</persistence>

数据源(在standalone.xml中定义):

datasource (defined in standalone.xml):

            <datasource jndi-name="java:jboss/datasources/Datasource" pool-name="DS" enabled="true" use-java-context="true">
                <connection-url>jdbc:mysql://localhost:3306/repository</connection-url>
                <connection-property name="useCompression">
                    false
                </connection-property>
                <connection-property name="logSlowQueries">
                    false
                </connection-property>
                <connection-property name="zeroDateTimeBehavior">
                    convertToNull
                </connection-property>
                <connection-property name="characterEncoding">
                    utf8
                </connection-property>
                <connection-property name="useUnicode">
                    true
                </connection-property>
                <connection-property name="connectionCollation">
                    utf8_unicode_ci
                </connection-property>
                <driver>mysql</driver>
                <security>
                    <user-name>user</user-name>
                    <password>TO_BE_DEFINED</password>
                </security>
            </datasource>

访问实体管理器:

@Stateless
@Local
public class GenericDataBean {

    @PersistenceContext(type=PersistenceContextType.TRANSACTION)
    private EntityManager em;

...
}

推荐答案

您的问题的一个可能解决方案是使用 数据源的>安全域.在您的情况下,您必须创建负责从加密存储加载密码的自定义登录模块.
您的配置应该类似于.

A possible solution for your problem is use a security domain for the datasource. In your case you must create custom login module responsible to load password from encrypted storage.
Your configuration should be similar to.

数据源:

<datasource ... >
   .....
   <security>
          <security-domain>EncryptedPassword</security-domain>
   </security>
</datasource>

安全管理:

<security-domain name="EncryptedPassword">
    <authentication>
        <login-module code="com.example.EncryptedPasswordLoginModule" flag="required">
            <!-- list of options -->
            <module-option name="username" value="theusername"/>
            <module-option name="managedConnectionFactoryName" value="jboss.jca:service=LocalTxCM,name=DS"/>
        </login-module>
    </authentication>
</security-domain>

登录模块实现:

public class EncryptedPasswordLoginModule
    extends AbstractPasswordCredentialLoginModule{

    private String username;

    public void initialize(Subject subject, CallbackHandler handler, Map sharedState, Map options){
        super.initialize(subject, handler, sharedState, options);
        username = (String) options.get("username");
        if( username == null ){
            throw new IllegalArgumentException("The user name is a required option");
        }

    }   

    public boolean login() throws LoginException{
        if( super.login() == true )
            return true;

        super.loginOk = true;
        return true;
    }

   public boolean commit() throws LoginException{
        Principal principal = new SimplePrincipal(username);
        SubjectActions.addPrincipals(subject, principal);
        sharedState.put("javax.security.auth.login.name", username);
        try{
            char[] password = .... //code to load encrypted password;
            PasswordCredential cred = new PasswordCredential(username, password);
            cred.setManagedConnectionFactory(getMcf());
            SubjectActions.addCredentials(subject, cred);
        }
        catch(Exception e){
            throw new LoginException("Failed to load encrypted password: "+e.getMessage());
        }
        return true;
   }

   public boolean abort(){
        username = null;
        return true;
   }

   protected Principal getIdentity(){
      Principal principal = new SimplePrincipal(username);
      return principal;
   }

   protected Group[] getRoleSets() throws LoginException{
      Group[] empty = new Group[0];
      return empty;
   }
}

也许这会有所帮助.

这篇关于Wildfly - 在运行时设置数据源密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆