23
23
using MongoDB . Bson . Serialization ;
24
24
using MongoDB . Driver . Core . Connections ;
25
25
using MongoDB . Driver . Core . Misc ;
26
- using MongoDB . Shared ;
27
26
28
27
namespace MongoDB . Driver . Core . Authentication
29
28
{
@@ -32,6 +31,73 @@ namespace MongoDB.Driver.Core.Authentication
32
31
/// </summary>
33
32
public class MongoAWSAuthenticator : SaslAuthenticator
34
33
{
34
+ internal static class ExternalAuthenticator
35
+ {
36
+ public static AwsCredentials CreateAwsCredentialsFromExternalSource ( string subject = "MONGODB-AWS authentication" ) =>
37
+ CreateAwsCredentialsFromExternalSourceAsync ( subject ) . GetAwaiter ( ) . GetResult ( ) ;
38
+
39
+ public static async Task < AwsCredentials > CreateAwsCredentialsFromExternalSourceAsync ( string subject = "MONGODB-AWS authentication" ) =>
40
+ CreateAwsCredentialsFromEnvironmentVariables ( subject ) ??
41
+ ( await CreateAwsCredentialsFromEcsResponseAsync ( ) . ConfigureAwait ( false ) ) ??
42
+ ( await CreateAwsCredentialsFromEc2ResponseAsync ( ) . ConfigureAwait ( false ) ) ??
43
+ throw new InvalidOperationException ( $ "Unable to find credentials for { subject } .") ;
44
+
45
+ // private methods
46
+ private static AwsCredentials CreateAwsCredentialsFromEnvironmentVariables ( string subject )
47
+ {
48
+ var accessKeyId = Environment . GetEnvironmentVariable ( "AWS_ACCESS_KEY_ID" ) ;
49
+ var secretAccessKey = Environment . GetEnvironmentVariable ( "AWS_SECRET_ACCESS_KEY" ) ;
50
+ var sessionToken = Environment . GetEnvironmentVariable ( "AWS_SESSION_TOKEN" ) ;
51
+
52
+ if ( accessKeyId == null && secretAccessKey == null && sessionToken == null )
53
+ {
54
+ return null ;
55
+ }
56
+ if ( secretAccessKey != null && accessKeyId == null )
57
+ {
58
+ throw new InvalidOperationException ( $ "When using { subject } if a secret access key is provided via environment variables then an access key ID must be provided also.") ;
59
+ }
60
+ if ( accessKeyId != null && secretAccessKey == null )
61
+ {
62
+ throw new InvalidOperationException ( $ "When using { subject } if an access key ID is provided via environment variables then a secret access key must be provided also.") ;
63
+ }
64
+ if ( sessionToken != null && ( accessKeyId == null || secretAccessKey == null ) )
65
+ {
66
+ throw new InvalidOperationException ( $ "When using { subject } if a session token is provided via environment variables then an access key ID and a secret access key must be provided also.") ;
67
+ }
68
+
69
+ return new AwsCredentials ( accessKeyId , SecureStringHelper . ToSecureString ( secretAccessKey ) , sessionToken ) ;
70
+ }
71
+
72
+ private static async Task < AwsCredentials > CreateAwsCredentialsFromEcsResponseAsync ( )
73
+ {
74
+ var relativeUri = Environment . GetEnvironmentVariable ( "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ) ;
75
+ if ( relativeUri == null )
76
+ {
77
+ return null ;
78
+ }
79
+
80
+ var response = await AwsHttpClientHelper . GetECSResponseAsync ( relativeUri ) . ConfigureAwait ( false ) ;
81
+ return CreateAwsCreadentialsFromAwsResponse ( response ) ;
82
+ }
83
+
84
+ private static async Task < AwsCredentials > CreateAwsCredentialsFromEc2ResponseAsync ( )
85
+ {
86
+ var response = await AwsHttpClientHelper . GetEC2ResponseAsync ( ) . ConfigureAwait ( false ) ;
87
+ return CreateAwsCreadentialsFromAwsResponse ( response ) ;
88
+ }
89
+
90
+ private static AwsCredentials CreateAwsCreadentialsFromAwsResponse ( string awsResponse )
91
+ {
92
+ var parsedResponse = BsonDocument . Parse ( awsResponse ) ;
93
+ var accessKeyId = parsedResponse . GetValue ( "AccessKeyId" , null ) ? . AsString ;
94
+ var secretAccessKey = parsedResponse . GetValue ( "SecretAccessKey" , null ) ? . AsString ;
95
+ var sessionToken = parsedResponse . GetValue ( "Token" , null ) ? . AsString ;
96
+
97
+ return new AwsCredentials ( accessKeyId , SecureStringHelper . ToSecureString ( secretAccessKey ) , sessionToken ) ;
98
+ }
99
+ }
100
+
35
101
// constants
36
102
private const int ClientNonceLength = 32 ;
37
103
@@ -72,14 +138,7 @@ private static MongoAWSMechanism CreateMechanism(
72
138
{
73
139
var awsCredentials =
74
140
CreateAwsCredentialsFromMongoCredentials ( username , password , properties ) ??
75
- CreateAwsCredentialsFromEnvironmentVariables ( ) ??
76
- CreateAwsCredentialsFromEcsResponse ( ) ??
77
- CreateAwsCredentialsFromEc2Response ( ) ;
78
-
79
- if ( awsCredentials == null )
80
- {
81
- throw new InvalidOperationException ( "Unable to find credentials for MONGODB-AWS authentication." ) ;
82
- }
141
+ ExternalAuthenticator . CreateAwsCredentialsFromExternalSource ( ) ;
83
142
84
143
return new MongoAWSMechanism ( awsCredentials , randomByteGenerator , clock ) ;
85
144
}
@@ -109,60 +168,6 @@ private static AwsCredentials CreateAwsCredentialsFromMongoCredentials(string us
109
168
return new AwsCredentials ( accessKeyId : username , secretAccessKey : password , sessionToken ) ;
110
169
}
111
170
112
- private static AwsCredentials CreateAwsCredentialsFromEnvironmentVariables ( )
113
- {
114
- var accessKeyId = Environment . GetEnvironmentVariable ( "AWS_ACCESS_KEY_ID" ) ;
115
- var secretAccessKey = Environment . GetEnvironmentVariable ( "AWS_SECRET_ACCESS_KEY" ) ;
116
- var sessionToken = Environment . GetEnvironmentVariable ( "AWS_SESSION_TOKEN" ) ;
117
-
118
- if ( accessKeyId == null && secretAccessKey == null && sessionToken == null )
119
- {
120
- return null ;
121
- }
122
- if ( secretAccessKey != null && accessKeyId == null )
123
- {
124
- throw new InvalidOperationException ( "When using MONGODB-AWS authentication if a secret access key is provided via environment variables then an access key ID must be provided also." ) ;
125
- }
126
- if ( accessKeyId != null && secretAccessKey == null )
127
- {
128
- throw new InvalidOperationException ( "When using MONGODB-AWS authentication if an access key ID is provided via environment variables then a secret access key must be provided also." ) ;
129
- }
130
- if ( sessionToken != null && ( accessKeyId == null || secretAccessKey == null ) )
131
- {
132
- throw new InvalidOperationException ( "When using MONGODB-AWS authentication if a session token is provided via environment variables then an access key ID and a secret access key must be provided also." ) ;
133
- }
134
-
135
- return new AwsCredentials ( accessKeyId , SecureStringHelper . ToSecureString ( secretAccessKey ) , sessionToken ) ;
136
- }
137
-
138
- private static AwsCredentials CreateAwsCredentialsFromEcsResponse ( )
139
- {
140
- var relativeUri = Environment . GetEnvironmentVariable ( "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ) ;
141
- if ( relativeUri == null )
142
- {
143
- return null ;
144
- }
145
-
146
- var response = AwsHttpClientHelper . GetECSResponseAsync ( relativeUri ) . GetAwaiter ( ) . GetResult ( ) ;
147
- var parsedResponse = BsonDocument . Parse ( response ) ;
148
- var accessKeyId = parsedResponse . GetValue ( "AccessKeyId" , null ) ? . AsString ;
149
- var secretAccessKey = parsedResponse . GetValue ( "SecretAccessKey" , null ) ? . AsString ;
150
- var sessionToken = parsedResponse . GetValue ( "Token" , null ) ? . AsString ;
151
-
152
- return new AwsCredentials ( accessKeyId , SecureStringHelper . ToSecureString ( secretAccessKey ) , sessionToken ) ;
153
- }
154
-
155
- private static AwsCredentials CreateAwsCredentialsFromEc2Response ( )
156
- {
157
- var response = AwsHttpClientHelper . GetEC2ResponseAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
158
- var parsedResponse = BsonDocument . Parse ( response ) ;
159
- var accessKeyId = parsedResponse . GetValue ( "AccessKeyId" , null ) ? . AsString ;
160
- var secretAccessKey = parsedResponse . GetValue ( "SecretAccessKey" , null ) ? . AsString ;
161
- var sessionToken = parsedResponse . GetValue ( "Token" , null ) ? . AsString ;
162
-
163
- return new AwsCredentials ( accessKeyId , SecureStringHelper . ToSecureString ( secretAccessKey ) , sessionToken ) ;
164
- }
165
-
166
171
private static string ExtractSessionTokenFromMechanismProperties ( IEnumerable < KeyValuePair < string , string > > properties )
167
172
{
168
173
if ( properties != null )
@@ -272,7 +277,7 @@ public override string DatabaseName
272
277
}
273
278
274
279
// nested classes
275
- private class AwsCredentials
280
+ internal class AwsCredentials
276
281
{
277
282
private readonly string _accessKeyId ;
278
283
private readonly SecureString _secretAccessKey ;
@@ -288,6 +293,14 @@ public AwsCredentials(string accessKeyId, SecureString secretAccessKey, string s
288
293
public string AccessKeyId => _accessKeyId ;
289
294
public SecureString SecretAccessKey => _secretAccessKey ;
290
295
public string SessionToken => _sessionToken ;
296
+
297
+ public BsonDocument ConvertToKmsCredentials ( ) =>
298
+ new BsonDocument
299
+ {
300
+ { "accessKeyId" , _accessKeyId } ,
301
+ { "secretAccessKey" , SecureStringHelper . ToInsecureString ( _secretAccessKey ) } ,
302
+ { "sessionToken" , _sessionToken , _sessionToken != null }
303
+ } ;
291
304
}
292
305
293
306
private static class AwsHttpClientHelper
0 commit comments