Skip to content

Commit ded8946

Browse files
Aws secretsmanager add type and json key support (#168)
* add missing parameter support and enhance JSON secret extraction * add missing parameter support and enhance JSON secret extraction * Address review comments
1 parent 8b7cc92 commit ded8946

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

ojdbc-provider-aws/README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ And the JSON Payload for the file **payload_ojdbc_objectstorage.json** in **mybu
7373
"user": "scott",
7474
"password": {
7575
"type": "awssecretsmanager",
76-
"value": "test-secret"
76+
"value": "test-secret",
77+
"field_name": "<field-name>" // Optional: Only needed when the secret is structured and contains multiple key-value pairs.
7778
},
7879
"jdbc": {
7980
"oracle.jdbc.ReadTimeout": 1000,
@@ -113,6 +114,12 @@ For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) th
113114
- Azure Key Vault URI (if azurevault)
114115
- Base64 Encoded password (if base64)
115116
- AWS Secret name (if awssecretsmanager)
117+
- field_name
118+
- Optional
119+
- Description: Specifies the key within the secret JSON object from which to extract the password value.
120+
If the secret JSON contains multiple key-value pairs, field_name must be provided to unambiguously select the desired secret value.
121+
If the secret contains only a single key-value pair and field_name is not provided, that sole value will be used.
122+
If the secret is provided as plain text (i.e., not structured as a JSON object), no field_name is required.
116123
- authentication
117124
- Optional
118125
- Possible Values

ojdbc-provider-aws/src/main/java/oracle/jdbc/provider/aws/configuration/AwsConfigurationParameters.java

+5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ private AwsConfigurationParameters() {}
5959
*/
6060
public static final Parameter<String> KEY = Parameter.create();
6161

62+
/**
63+
* The field name for extracting a specific value from the JSON.
64+
*/
65+
public static final Parameter<String> FIELD_NAME = Parameter.create();
66+
6267
/**
6368
* Configures a {@code builder} to build a parser that recognizes the common
6469
* set of parameters accepted by {@link AwsS3ConfigurationProvider} and

ojdbc-provider-aws/src/main/java/oracle/jdbc/provider/aws/configuration/AwsJsonSecretsManagerProvider.java

+45-2
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,23 @@
4040
import oracle.jdbc.provider.aws.secrets.SecretsManagerFactory;
4141
import oracle.jdbc.provider.parameter.ParameterSet;
4242
import oracle.jdbc.spi.OracleConfigurationSecretProvider;
43+
import oracle.sql.json.OracleJsonException;
44+
import oracle.sql.json.OracleJsonFactory;
4345
import oracle.sql.json.OracleJsonObject;
4446

47+
import java.io.ByteArrayInputStream;
48+
import java.nio.charset.StandardCharsets;
4549
import java.util.Base64;
4650
import java.util.Map;
4751

52+
import static oracle.jdbc.provider.aws.configuration.AwsConfigurationParameters.FIELD_NAME;
4853
import static oracle.jdbc.provider.aws.configuration.AwsSecretsManagerConfigurationProvider.PARAMETER_SET_PARSER;
4954

5055
public class AwsJsonSecretsManagerProvider
5156
implements OracleConfigurationSecretProvider {
57+
58+
private static final OracleJsonFactory JSON_FACTORY = new OracleJsonFactory();
59+
5260
/**
5361
* {@inheritDoc}
5462
* <p>
@@ -62,24 +70,59 @@ public class AwsJsonSecretsManagerProvider
6270
* <pre>{@code
6371
* "password": {
6472
* "type": "awssecretsmanager",
65-
* "value": "<secret-name>"
73+
* "value": "<secret-name>",
74+
* "field_name": "<field-name>"
6675
* }
6776
* }</pre>
6877
*
78+
* <p>
79+
* The {@code field_name} parameter indicates the key whose value should
80+
* be extracted as the secret. When there are multiple key-value pairs
81+
* present, specifying this parameter is mandatory in order to
82+
* unambiguously select the desired secret value. If the secret contains
83+
* only a single entry and no {@code field_name} is provided, that sole
84+
* value will be used. In cases where the secret is plain text,
85+
* the {@code field_name} parameter is not required.
86+
* </p>
87+
*
6988
* @param map Map object to be parsed
7089
* @return encoded char array in base64 format that represents the retrieved
7190
* Secret.
7291
*/
7392
@Override
7493
public char[] getSecret(Map<String, String> map) {
7594
ParameterSet parameterSet = PARAMETER_SET_PARSER.parseNamedValues(map);
95+
String fieldName = parameterSet.getOptional(FIELD_NAME);
7696

7797
String secretString = SecretsManagerFactory.getInstance()
7898
.request(parameterSet)
7999
.getContent();
80100

101+
String extractedSecret;
102+
103+
try {
104+
OracleJsonObject jsonObject = JSON_FACTORY.createJsonTextValue(
105+
new ByteArrayInputStream(secretString.getBytes(StandardCharsets.UTF_8)))
106+
.asJsonObject();
107+
108+
if (fieldName != null) {
109+
if (!jsonObject.containsKey(fieldName)) {
110+
throw new IllegalStateException("Field '" + fieldName + "' not found in secret JSON.");
111+
}
112+
extractedSecret = jsonObject.get(fieldName).asJsonString().getString();
113+
} else if (jsonObject.size() == 1) {
114+
extractedSecret = jsonObject.values().iterator().next().asJsonString().getString();
115+
} else {
116+
throw new IllegalStateException(
117+
"FIELD_NAME is required when multiple keys exist in the secret JSON");
118+
}
119+
120+
} catch (OracleJsonException e) {
121+
extractedSecret = secretString;
122+
}
123+
81124
return Base64.getEncoder()
82-
.encodeToString(secretString.getBytes())
125+
.encodeToString(extractedSecret.getBytes(StandardCharsets.UTF_8))
83126
.toCharArray();
84127
}
85128

ojdbc-provider-aws/src/main/java/oracle/jdbc/provider/aws/configuration/AwsSecretsManagerConfigurationProvider.java

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import oracle.jdbc.driver.configuration.OracleConfigurationParsableProvider;
4141
import oracle.jdbc.provider.aws.secrets.SecretsManagerFactory;
42+
import oracle.jdbc.provider.parameter.Parameter;
4243
import oracle.jdbc.provider.parameter.ParameterSet;
4344
import oracle.jdbc.provider.parameter.ParameterSetParser;
4445
import oracle.jdbc.util.OracleConfigurationCache;
@@ -64,6 +65,8 @@ public class AwsSecretsManagerConfigurationProvider extends OracleConfigurationP
6465
ParameterSetParser.builder()
6566
.addParameter("value", SecretsManagerFactory.SECRET_NAME)
6667
.addParameter("key", AwsConfigurationParameters.KEY)
68+
.addParameter("type", Parameter.create())
69+
.addParameter("field_name", AwsConfigurationParameters.FIELD_NAME)
6770
.addParameter("AWS_REGION", AwsConfigurationParameters.REGION))
6871
.build();
6972

0 commit comments

Comments
 (0)