我正在使用 Jboss wildfly 8.1 和 JPA Hibernate 开发服务器应用程序。问题是,JPA 数据源信用必须在运行时加载(密码)。当服务器启动时,它会连接到加密存储,并在其中检索真实数据库的密码。之后,它应该建立与真实数据库的连接。
我已经尝试了几件事:
通过JNDI查找数据源并与实际DS重新绑定。
通过JNDI查找entityManagerFactory并使用自定义EntityManager重新绑定它。
但这些都不起作用。你知道如何解决吗?
我的配置:
持久性.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 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;
...
}
您的问题的一个可能的解决方案是使用安全域为了数据源。
在你的情况下,你必须创建自定义登录模块负责从加密存储加载密码。
您的配置应该类似于。
数据源:
<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;
}
}
也许这会有所帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)