Skip to content

Commit 44d0ce9

Browse files
authored
RUST-479 / RUST-502 Improve authSource handling (#215)
1 parent d60c7c4 commit 44d0ce9

File tree

5 files changed

+256
-12
lines changed

5 files changed

+256
-12
lines changed

src/client/options/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,13 @@ impl ClientOptionsParser {
944944
}
945945
}
946946

947+
if options.auth_source.as_deref() == Some("") {
948+
return Err(ErrorKind::ArgumentError {
949+
message: "empty authSource provided".to_string(),
950+
}
951+
.into());
952+
}
953+
947954
let db_str = db.as_deref();
948955

949956
match options.auth_mechanism {
@@ -995,13 +1002,6 @@ impl ClientOptionsParser {
9951002
.to_string(),
9961003
}
9971004
.into());
998-
} else if options.auth_source.is_some() {
999-
return Err(ErrorKind::ArgumentError {
1000-
message: "username and mechanism both not provided, but authSource was \
1001-
specified"
1002-
.to_string(),
1003-
}
1004-
.into());
10051005
}
10061006
}
10071007
};

src/test/spec/auth.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ async fn run_auth_test(test_file: TestFile) {
5050
for mut test_case in test_file.tests {
5151
test_case.description = test_case.description.replace('$', "%");
5252

53-
let skipped_mechanisms = ["GSSAPI", "MONGODB-X509", "PLAIN", "MONGODB-CR"];
53+
let skipped_mechanisms = [
54+
"GSSAPI",
55+
"MONGODB-X509",
56+
"PLAIN",
57+
"MONGODB-CR",
58+
"MONGODB-AWS",
59+
];
5460

5561
// TODO: X509 (RUST-147)
5662
// TODO: GSSAPI (RUST-196)

src/test/spec/json/auth/connection-string.json

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@
107107
}
108108
}
109109
},
110+
{
111+
"description": "must raise an error when the authSource is empty",
112+
"uri": "mongodb://user:password@localhost/foo?authSource=",
113+
"valid": false
114+
},
115+
{
116+
"description": "must raise an error when the authSource is empty without credentials",
117+
"uri": "mongodb://localhost/admin?authSource=",
118+
"valid": false
119+
},
110120
{
111121
"description": "should throw an exception if authSource is invalid (GSSAPI)",
112122
"uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=foo",
@@ -206,6 +216,18 @@
206216
"mechanism_properties": null
207217
}
208218
},
219+
{
220+
"description": "should recognize the mechanism with no username when auth source is explicitly specified (MONGODB-X509)",
221+
"uri": "mongodb://localhost/?authMechanism=MONGODB-X509&authSource=$external",
222+
"valid": true,
223+
"credential": {
224+
"username": null,
225+
"password": null,
226+
"source": "$external",
227+
"mechanism": "MONGODB-X509",
228+
"mechanism_properties": null
229+
}
230+
},
209231
{
210232
"description": "should throw an exception if supplied a password (MONGODB-X509)",
211233
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-X509",
@@ -352,9 +374,10 @@
352374
"credential": null
353375
},
354376
{
355-
"description": "authSource without username is invalid (default mechanism)",
377+
"description": "authSource without username doesn't create credential (default mechanism)",
356378
"uri": "mongodb://localhost/?authSource=foo",
357-
"valid": false
379+
"valid": true,
380+
"credential": null
358381
},
359382
{
360383
"description": "should throw an exception if no username provided (userinfo implies default mechanism)",
@@ -365,6 +388,62 @@
365388
"description": "should throw an exception if no username/password provided (userinfo implies default mechanism)",
366389
"uri": "mongodb://:@localhost.com/",
367390
"valid": false
391+
},
392+
{
393+
"description": "should recognise the mechanism (MONGODB-AWS)",
394+
"uri": "mongodb://localhost/?authMechanism=MONGODB-AWS",
395+
"valid": true,
396+
"credential": {
397+
"username": null,
398+
"password": null,
399+
"source": "$external",
400+
"mechanism": "MONGODB-AWS",
401+
"mechanism_properties": null
402+
}
403+
},
404+
{
405+
"description": "should recognise the mechanism when auth source is explicitly specified (MONGODB-AWS)",
406+
"uri": "mongodb://localhost/?authMechanism=MONGODB-AWS&authSource=$external",
407+
"valid": true,
408+
"credential": {
409+
"username": null,
410+
"password": null,
411+
"source": "$external",
412+
"mechanism": "MONGODB-AWS",
413+
"mechanism_properties": null
414+
}
415+
},
416+
{
417+
"description": "should throw an exception if username and no password (MONGODB-AWS)",
418+
"uri": "mongodb://user@localhost/?authMechanism=MONGODB-AWS",
419+
"valid": false,
420+
"credential": null
421+
},
422+
{
423+
"description": "should use username and password if specified (MONGODB-AWS)",
424+
"uri": "mongodb://user%21%40%23%24%25%5E%26%2A%28%29_%2B:pass%21%40%23%24%25%5E%26%2A%28%29_%2B@localhost/?authMechanism=MONGODB-AWS",
425+
"valid": true,
426+
"credential": {
427+
"username": "user!@#$%^&*()_+",
428+
"password": "pass!@#$%^&*()_+",
429+
"source": "$external",
430+
"mechanism": "MONGODB-AWS",
431+
"mechanism_properties": null
432+
}
433+
},
434+
{
435+
"description": "should use username, password and session token if specified (MONGODB-AWS)",
436+
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:token%21%40%23%24%25%5E%26%2A%28%29_%2B",
437+
"valid": true,
438+
"credential": {
439+
"username": "user",
440+
"password": "password",
441+
"source": "$external",
442+
"mechanism": "MONGODB-AWS",
443+
"mechanism_properties": {
444+
"AWS_SESSION_TOKEN": "token!@#$%^&*()_+"
445+
}
446+
}
368447
}
369448
]
370449
}

src/test/spec/json/auth/connection-string.yml

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ tests:
8585
mechanism: "GSSAPI"
8686
mechanism_properties:
8787
SERVICE_NAME: "mongodb"
88+
-
89+
description: "must raise an error when the authSource is empty"
90+
uri: "mongodb://user:password@localhost/foo?authSource="
91+
valid: false
92+
-
93+
description: "must raise an error when the authSource is empty without credentials"
94+
uri: "mongodb://localhost/admin?authSource="
95+
valid: false
8896
-
8997
description: "should throw an exception if authSource is invalid (GSSAPI)"
9098
uri: "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=foo"
@@ -167,6 +175,16 @@ tests:
167175
source: "$external"
168176
mechanism: "MONGODB-X509"
169177
mechanism_properties: ~
178+
-
179+
description: "should recognize the mechanism with no username when auth source is explicitly specified (MONGODB-X509)"
180+
uri: "mongodb://localhost/?authMechanism=MONGODB-X509&authSource=$external"
181+
valid: true
182+
credential:
183+
username: ~
184+
password: ~
185+
source: "$external"
186+
mechanism: "MONGODB-X509"
187+
mechanism_properties: ~
170188
-
171189
description: "should throw an exception if supplied a password (MONGODB-X509)"
172190
uri: "mongodb://user:password@localhost/?authMechanism=MONGODB-X509"
@@ -288,9 +306,10 @@ tests:
288306
valid: true
289307
credential: ~
290308
-
291-
description: "authSource without username is invalid (default mechanism)"
309+
description: "authSource without username doesn't create credential (default mechanism)"
292310
uri: "mongodb://localhost/?authSource=foo"
293-
valid: false
311+
valid: true
312+
credential: ~
294313
-
295314
description: "should throw an exception if no username provided (userinfo implies default mechanism)"
296315
uri: "mongodb://@localhost.com/"
@@ -299,3 +318,49 @@ tests:
299318
description: "should throw an exception if no username/password provided (userinfo implies default mechanism)"
300319
uri: "mongodb://:@localhost.com/"
301320
valid: false
321+
-
322+
description: "should recognise the mechanism (MONGODB-AWS)"
323+
uri: "mongodb://localhost/?authMechanism=MONGODB-AWS"
324+
valid: true
325+
credential:
326+
username: ~
327+
password: ~
328+
source: "$external"
329+
mechanism: "MONGODB-AWS"
330+
mechanism_properties: ~
331+
-
332+
description: "should recognise the mechanism when auth source is explicitly specified (MONGODB-AWS)"
333+
uri: "mongodb://localhost/?authMechanism=MONGODB-AWS&authSource=$external"
334+
valid: true
335+
credential:
336+
username: ~
337+
password: ~
338+
source: "$external"
339+
mechanism: "MONGODB-AWS"
340+
mechanism_properties: ~
341+
-
342+
description: "should throw an exception if username and no password (MONGODB-AWS)"
343+
uri: "mongodb://user@localhost/?authMechanism=MONGODB-AWS"
344+
valid: false
345+
credential: ~
346+
-
347+
description: "should use username and password if specified (MONGODB-AWS)"
348+
uri: "mongodb://user%21%40%23%24%25%5E%26%2A%28%29_%2B:pass%21%40%23%24%25%5E%26%2A%28%29_%2B@localhost/?authMechanism=MONGODB-AWS"
349+
valid: true
350+
credential:
351+
username: "user!@#$%^&*()_+"
352+
password: "pass!@#$%^&*()_+"
353+
source: "$external"
354+
mechanism: "MONGODB-AWS"
355+
mechanism_properties: ~
356+
-
357+
description: "should use username, password and session token if specified (MONGODB-AWS)"
358+
uri: "mongodb://user:password@localhost/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:token%21%40%23%24%25%5E%26%2A%28%29_%2B"
359+
valid: true
360+
credential:
361+
username: "user"
362+
password: "password"
363+
source: "$external"
364+
mechanism: "MONGODB-AWS"
365+
mechanism_properties:
366+
AWS_SESSION_TOKEN: "token!@#$%^&*()_+"
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
===========
2+
MongoDB AWS
3+
===========
4+
5+
There are 5 scenarios drivers MUST test:
6+
7+
#. ``Regular Credentials``: Auth via an ``ACCESS_KEY_ID`` and ``SECRET_ACCESS_KEY`` pair
8+
#. ``EC2 Credentials``: Auth from an EC2 instance via temporary credentials assigned to the machine
9+
#. ``ECS Credentials``: Auth from an ECS instance via temporary credentials assigned to the task
10+
#. ``Assume Role``: Auth via temporary credentials obtained from an STS AssumeRole request
11+
#. ``AWS Lambda``: Auth via environment variables ``AWS_ACCESS_KEY_ID``, ``AWS_SECRET_ACCESS_KEY``, and ``AWS_SESSION_TOKEN``.
12+
13+
For brevity, this section gives the values ``<AccessKeyId>``, ``<SecretAccessKey>`` and ``<Token>`` in place of a valid access key ID, secret access key and session token (also known as a security token). Note that if these values are passed into the URI they MUST be URL encoded. Sample values are below.
14+
15+
.. code-block::
16+
17+
AccessKeyId=AKIAI44QH8DHBEXAMPLE
18+
SecretAccessKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
19+
Token=AQoDYXdzEJr...<remainder of security token>
20+
|
21+
.. sectnum::
22+
23+
Regular credentials
24+
======================
25+
26+
Drivers MUST be able to authenticate by providing a valid access key id and secret access key pair as the username and password, respectively, in the MongoDB URI. An example of a valid URI would be:
27+
28+
.. code-block::
29+
30+
mongodb://<AccessKeyId>:<SecretAccessKey>@localhost/?authMechanism=MONGODB-AWS
31+
|
32+
EC2 Credentials
33+
===============
34+
35+
Drivers MUST be able to authenticate from an EC2 instance via temporary credentials assigned to the machine. A sample URI on an EC2 machine would be:
36+
37+
.. code-block::
38+
39+
mongodb://localhost/?authMechanism=MONGODB-AWS
40+
|
41+
.. note:: No username, password or session token is passed into the URI. Drivers MUST query the EC2 instance endpoint to obtain these credentials.
42+
43+
ECS instance
44+
============
45+
46+
Drivers MUST be able to authenticate from an ECS container via temporary credentials. A sample URI in an ECS container would be:
47+
48+
.. code-block::
49+
50+
mongodb://localhost/?authMechanism=MONGODB-AWS
51+
|
52+
.. note:: No username, password or session token is passed into the URI. Drivers MUST query the ECS container endpoint to obtain these credentials.
53+
54+
AssumeRole
55+
==========
56+
57+
Drivers MUST be able to authenticate using temporary credentials returned from an assume role request. These temporary credentials consist of an access key ID, a secret access key, and a security token passed into the URI. A sample URI would be:
58+
59+
.. code-block::
60+
61+
mongodb://<AccessKeyId>:<SecretAccessKey>@localhost/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:<Token>
62+
|
63+
AWS Lambda
64+
==========
65+
66+
Drivers MUST be able to authenticate via an access key ID, secret access key and optional session token taken from the environment variables, respectively:
67+
68+
.. code-block::
69+
70+
AWS_ACCESS_KEY_ID
71+
AWS_SECRET_ACCESS_KEY
72+
AWS_SESSION_TOKEN
73+
|
74+
75+
Sample URIs both with and without optional session tokens set are shown below. Drivers MUST test both cases.
76+
77+
.. code-block:: bash
78+
79+
# without a session token
80+
export AWS_ACCESS_KEY_ID="<AccessKeyId>"
81+
export AWS_SECRET_ACCESS_KEY="<SecretAccessKey>"
82+
83+
URI="mongodb://localhost/?authMechanism=MONGODB-AWS"
84+
|
85+
.. code-block:: bash
86+
87+
# with a session token
88+
export AWS_ACCESS_KEY_ID="<AccessKeyId>"
89+
export AWS_SECRET_ACCESS_KEY="<SecretAccessKey>"
90+
export AWS_SESSION_TOKEN="<Token>"
91+
92+
URI="mongodb://localhost/?authMechanism=MONGODB-AWS"
93+
|
94+
.. note:: No username, password or session token is passed into the URI. Drivers MUST check the environment variables listed above for these values. If the session token is set Drivers MUST use it.

0 commit comments

Comments
 (0)