40
40
import oracle .jdbc .provider .aws .secrets .SecretsManagerFactory ;
41
41
import oracle .jdbc .provider .parameter .ParameterSet ;
42
42
import oracle .jdbc .spi .OracleConfigurationSecretProvider ;
43
+ import oracle .sql .json .OracleJsonException ;
44
+ import oracle .sql .json .OracleJsonFactory ;
43
45
import oracle .sql .json .OracleJsonObject ;
44
46
47
+ import java .io .ByteArrayInputStream ;
48
+ import java .nio .charset .StandardCharsets ;
45
49
import java .util .Base64 ;
46
50
import java .util .Map ;
47
51
52
+ import static oracle .jdbc .provider .aws .configuration .AwsConfigurationParameters .FIELD_NAME ;
48
53
import static oracle .jdbc .provider .aws .configuration .AwsSecretsManagerConfigurationProvider .PARAMETER_SET_PARSER ;
49
54
50
55
public class AwsJsonSecretsManagerProvider
51
56
implements OracleConfigurationSecretProvider {
57
+
58
+ private static final OracleJsonFactory JSON_FACTORY = new OracleJsonFactory ();
59
+
52
60
/**
53
61
* {@inheritDoc}
54
62
* <p>
@@ -62,24 +70,59 @@ public class AwsJsonSecretsManagerProvider
62
70
* <pre>{@code
63
71
* "password": {
64
72
* "type": "awssecretsmanager",
65
- * "value": "<secret-name>"
73
+ * "value": "<secret-name>",
74
+ * "field_name": "<field-name>"
66
75
* }
67
76
* }</pre>
68
77
*
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
+ *
69
88
* @param map Map object to be parsed
70
89
* @return encoded char array in base64 format that represents the retrieved
71
90
* Secret.
72
91
*/
73
92
@ Override
74
93
public char [] getSecret (Map <String , String > map ) {
75
94
ParameterSet parameterSet = PARAMETER_SET_PARSER .parseNamedValues (map );
95
+ String fieldName = parameterSet .getOptional (FIELD_NAME );
76
96
77
97
String secretString = SecretsManagerFactory .getInstance ()
78
98
.request (parameterSet )
79
99
.getContent ();
80
100
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
+
81
124
return Base64 .getEncoder ()
82
- .encodeToString (secretString .getBytes ())
125
+ .encodeToString (extractedSecret .getBytes (StandardCharsets . UTF_8 ))
83
126
.toCharArray ();
84
127
}
85
128
0 commit comments