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

查看:96
本文介绍了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?

我的配置:

persistence.xml:

persistence.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天全站免登陆