Skip to content

Commit

Permalink
New PersistenceUnit property - eclipselink.login.encryptor (#2126)
Browse files Browse the repository at this point in the history
New non-internal org.eclipse.persistence.security.Securable interface to implement custom password encryptor


(cherry picked from commit c8f43af)

Signed-off-by: Radek Felcman <radek.felcman@oracle.com>
  • Loading branch information
rfelcman authored May 3, 2024
1 parent 5481aa4 commit f8c88be
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 8 deletions.
62 changes: 61 additions & 1 deletion docs/docs.jpa/src/main/asciidoc/persistenceproperties_ref.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2022, 2024 Oracle and/or its affiliates. All rights reserved.

This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -88,6 +88,7 @@ customizing descriptors and sessions:
* link:#metadatasourcepropertiesfile[`metadata-source.properties.file`]
* link:#metadatasourcesendrefreshcommand[`metadata-source.send-refresh-command`]
* link:#metadatasourcexmlurl[`metadata-source.xml.url`]
* link:#loginencryptor[`login.encryptor`]
[[CACJHFEC2]][[TLJPA1051]]
Expand Down Expand Up @@ -339,6 +340,7 @@ The following lists the EclipseLink persistence property
* link:#loggingsession[`logging.session`]
* link:#loggingthread[`logging.thread`]
* link:#loggingtimestamp[`logging.timestamp`]
* link:#login-encryptor[`login.encryptor`]
* link:#locking-timestamp-local[`locking.timestamp.local`]
* link:#metadatasource[`metadata-source`]
* link:#metadatasourcepropertiesfile[`metadata-source.properties.file`]
Expand Down Expand Up @@ -6456,6 +6458,64 @@ _Solutions Guide for EclispeLink_
'''''
=== login.encryptor
Use the `eclipselink.login.encryptor` property to specify a custom
implementation of class that implements the
`org.eclipse.persistence.security.Securable` interface. The class
must provide a default, no argument constructor.
*Values*
link:#CHDGBEFGA[Table 5-89] describes this persistence property's values.
[[CHDGBEFGA]]
*_Table 5-89 Valid Values for login.encryptor_*
|======================================================================
|*Value* |*Description*
|class name |Fully qualified class name of custom implementation `org.eclipse.persistence.security.Securable` class.
|======================================================================
*Usage*
It is used to encrypt and decrypt database password loaded from
`jakarta.persistence.jdbc.password` property.
Usage of this property avoids limitation of link:#sessioncustomizer[`session.customizer`] which is called when all other
properties have been processed (too late when database login needs to be configured).
*Examples*
link:#CHDFBIEIA[Example 5-109] shows how to use this property in the
`persistence.xml` file.
[[CHDFBIEIA]][[TLJPA1015]]
*_Example 5-109 Using login.encryptor in persistence.xml_*
[source,oac_no_warn]
----
<property name="eclipselink.login.encryptor"
value="acme.sessions.MyEncryptor"/>
----
link:#CHDJEDJGA[Example 5-110] shows how to use this property in a
property map.
[[CHDJEDJGA]][[TLJPA1016]]
*_Example 5-110 Using session.customizer in a Property Map_*
[source,oac_no_warn]
----
import org.eclipse.persistence.config.PersistenceUnitProperties;
propertiesMap.put(PersistenceUnitProperties.LOGIN_ENCRYPTOR,
"acme.sessions.MyEncryptor");
----
'''''
=== locking.timestamp.local
This property defines if locking policies should default to local time(true) or server time(false).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -14,8 +14,7 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.sessionsxml;

import org.eclipse.persistence.internal.security.Securable;

import org.eclipse.persistence.security.Securable;

public class CustomEncryption implements Securable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4161,6 +4161,22 @@ public class PersistenceUnitProperties {
*/
public static final String QUERY_RESULTS_CACHE_VALIDATION = "eclipselink.query-results-cache.validation";

/**
* The "<code>eclipselink.login.encryptor</code>" property configures a custom implementation of
* {@link org.eclipse.persistence.security.Securable} class used to encrypt and decrypt database password
* loaded from "<code>jakarta.persistence.jdbc.password</code>" property.
* If this property is not specified {@link org.eclipse.persistence.internal.security.JCEEncryptor} as a default encryptor is used.
* <p>
* <b>Allowed Values:</b>
* <ul>
* <li>the fully qualified name for a class that implements {@link org.eclipse.persistence.security.Securable} interface
* </ul>
*
* @see org.eclipse.persistence.security.Securable
* @see org.eclipse.persistence.internal.security.JCEEncryptor
*/
public static final String LOGIN_ENCRYPTOR = "eclipselink.login.encryptor";

/**
* INTERNAL: The following properties will not be displayed through logging
* but instead have an alternate value shown in the log.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -112,7 +112,7 @@ private void initSecurableObject() {
* At runtime, no encryption will be made and the passwords will be assummed to
* be clear text.
*/
private static final class PassThroughEncryptor implements Securable {
private static final class PassThroughEncryptor implements org.eclipse.persistence.security.Securable {
@Override
public String encryptPassword(String pswd) {
return pswd;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Copyright (c) 2018, 2022 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, 2024 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -21,6 +21,7 @@
<property name="eclipselink.session-name" value="JPASessionXML"/>
<property name="eclipselink.exception-handler" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedExceptionHandler"/>
<property name="eclipselink.session-event-listener" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedSessionEventListener"/>
<property name="eclipselink.login.encryptor" value="org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties.CustomizedEncryptor"/>
<property name="eclipselink.jdbc.batch-writing" value="BUFFERED"/>
<property name="eclipselink.jdbc.native-sql" value="true"/>
<property name="eclipselink.jdbc.cache-statements.size" value="100"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.jpa.jpaadvancedproperties;

import org.eclipse.persistence.security.Securable;

public class CustomizedEncryptor implements Securable {

public static int encryptPasswordCounter = 0;
public static int decryptPasswordCounter = 0;

@Override
public String encryptPassword(String pswd) {
encryptPasswordCounter++;
return pswd;
}

@Override
public String decryptPassword(String encryptedPswd) {
decryptPasswordCounter++;
return encryptedPswd;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -63,6 +63,7 @@ public static Test suite() {
suite.addTest(new JPAAdvPropertiesTest("testBatchwritingProperty"));
suite.addTest(new JPAAdvPropertiesTest("testCopyDescriptorNamedQueryToSessionProperty"));
suite.addTest(new JPAAdvPropertiesTest("testLoggingTyperProperty"));
suite.addTest(new JPAAdvPropertiesTest("testLoginEncryptorProperty"));

return suite;
}
Expand Down Expand Up @@ -299,4 +300,29 @@ public void testSessionXMLProperty() {
assertNull("Error deleting Customer", em.find(Customer.class, customerId));

}

public void testLoginEncryptorProperty() {
EntityManager em = createEntityManager();
try {
//Create new customer
beginTransaction(em);
Customer customer = ModelExamples.customerExample1();
em.persist(customer);
em.flush();
Integer customerId = customer.getCustomerId();
commitTransaction(em);

customer = em.find(org.eclipse.persistence.testing.models.jpa.jpaadvancedproperties.Customer.class, customerId);
//Purge it
beginTransaction(em);
em.remove(customer);
commitTransaction(em);

assertNotNull(customer);
assertTrue("CustomizedEncryptor.encryptPassword() method wasn't called.", CustomizedEncryptor.encryptPasswordCounter > 0);
assertTrue("CustomizedEncryptor.decryptPassword() method wasn't called.", CustomizedEncryptor.decryptPasswordCounter > 0);
} finally {
closeEntityManager(em);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2506,6 +2506,11 @@ protected void updateLogins(Map m){
login.setProperty(property, value);
}

String encryptionClassName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGIN_ENCRYPTOR, m, this.session);
if (encryptionClassName != null) {
this.securableObjectHolder.setEncryptionClassName(encryptionClassName);
login.setEncryptionClassName(encryptionClassName);
}
// Note: This call does not checked the stored persistenceUnitInfo or extended properties because
// the map passed into this method should represent the full set of properties we expect to process

Expand Down

0 comments on commit f8c88be

Please sign in to comment.