Skip to content

Commit 7cdd013

Browse files
papafesanych-sun
andauthored
CSHARP-5471: Incorrectly resolving the authentication mechanism param… (#1605)
Co-authored-by: Oleksandr Poliakov <[email protected]>
1 parent a6f84f2 commit 7cdd013

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

src/MongoDB.Driver/Core/Configuration/ConnectionString.cs

+17-16
Original file line numberDiff line numberDiff line change
@@ -684,29 +684,30 @@ private ConnectionString BuildResolvedConnectionString(ConnectionStringScheme re
684684
.AllKeys
685685
.SelectMany(key => resolvedOptions
686686
.GetValues(key)
687-
.Select(value => $"{key}={Uri.EscapeDataString(value)}")));
687+
.Select(value => $"{key}={EscapeOptionValue(key, value)}")));
688688

689689
if (mergedOptions.Count > 0)
690690
{
691691
connectionString += "?" + string.Join("&", mergedOptions);
692692
}
693693

694694
return new ConnectionString(connectionString, isResolved: true);
695+
696+
string EscapeOptionValue(string key, string value)
697+
=> string.Equals(key, "authmechanismproperties", StringComparison.OrdinalIgnoreCase) ? value : Uri.EscapeDataString(value);
698+
695699
}
696700

697701
private void ExtractScheme(Match match)
698702
{
699703
var schemeGroup = match.Groups["scheme"];
700-
if (schemeGroup.Success)
704+
if (schemeGroup.Success && schemeGroup.Value == "mongodb+srv")
701705
{
702-
if (schemeGroup.Value == "mongodb+srv")
706+
_scheme = ConnectionStringScheme.MongoDBPlusSrv;
707+
if (!_tls.HasValue)
703708
{
704-
_scheme = ConnectionStringScheme.MongoDBPlusSrv;
705-
if (!_tls.HasValue)
706-
{
707-
_tls = true;
708-
_allOptions.Add("tls", "true");
709-
}
709+
_tls = true;
710+
_allOptions.Add("tls", "true");
710711
}
711712
}
712713
}
@@ -761,7 +762,13 @@ private void ExtractOptions(Match match)
761762
var parts = option.Value.Split('=');
762763
var name = parts[0].Trim();
763764
var value = parts[1].Trim();
764-
_allOptions.Add(name, Uri.UnescapeDataString(value));
765+
// Should not decode authmechanismproperties before splitting by separator.
766+
if (!string.Equals(name, "authmechanismproperties", StringComparison.OrdinalIgnoreCase))
767+
{
768+
value = Uri.UnescapeDataString(value);
769+
}
770+
771+
_allOptions.Add(name, value);
765772
ParseOption(name, value);
766773
}
767774
}
@@ -905,12 +912,6 @@ string ProtectConnectionString(string connectionString)
905912

906913
private void ParseOption(string name, string value)
907914
{
908-
// Should not decode authmechanismproperties before splitting by separator.
909-
if (!string.Equals(name, "authmechanismproperties", StringComparison.OrdinalIgnoreCase))
910-
{
911-
value = Uri.UnescapeDataString(value);
912-
}
913-
914915
switch (name.ToLowerInvariant())
915916
{
916917
case "appname":

tests/MongoDB.Driver.Tests/MongoCredentialTests.cs

+24
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,29 @@ public void TestMechanismProperty()
155155
Assert.Equal("awesome", withProperties.GetMechanismProperty<string>("SPN", null));
156156
Assert.Equal(10, withProperties.GetMechanismProperty<int>("OTHER", 0));
157157
}
158+
159+
[Theory]
160+
[InlineData("mongodb+srv://<cluster>/?retryWrites=true&authMechanism=MONGODB-OIDC&authSource=%24external&authMechanismProperties=ENVIRONMENT:azure,prop:ab%2Ccd%2Cef%2Cjh,TOKEN_RESOURCE:mongodb%3A%2F%2Ftest-cluster,ANOTHER:test")]
161+
[InlineData("mongodb+srv://<cluster>/?retryWrites=true&authMechanism=MONGODB-OIDC&authSource=%24external&authMechanismProperties=ENVIRONMENT:azure,prop:ab%2Ccd%2Cef%2Cjh,TOKEN_RESOURCE:mongodb://test-cluster,ANOTHER:test")]
162+
public void TestMechanismPropertyFromUnresolvedConnectionString(string url)
163+
{
164+
var mongoConnection = MongoClientSettings.FromConnectionString(url);
165+
mongoConnection.Credential.GetMechanismProperty("ENVIRONMENT", "").Should().Be("azure");
166+
mongoConnection.Credential.GetMechanismProperty("prop", "").Should().Be("ab,cd,ef,jh");
167+
mongoConnection.Credential.GetMechanismProperty("TOKEN_RESOURCE", "").Should().Be("mongodb://test-cluster");
168+
mongoConnection.Credential.GetMechanismProperty("ANOTHER", "").Should().Be("test");
169+
}
170+
171+
[Theory]
172+
[InlineData("mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authSource=$external&authMechanismProperties=ENVIRONMENT:azure,prop:ab%2Ccd%2Cef%2Cjh,TOKEN_RESOURCE:mongodb%3A%2F%2Ftest-cluster,ANOTHER:test")]
173+
[InlineData("mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authSource=$external&authMechanismProperties=ENVIRONMENT:azure,prop:ab%2Ccd%2Cef%2Cjh,TOKEN_RESOURCE:mongodb://test-cluster,ANOTHER:test")]
174+
public void TestMechanismPropertyFromResolvedConnectionString(string url)
175+
{
176+
var mongoConnection = MongoClientSettings.FromConnectionString(url);
177+
mongoConnection.Credential.GetMechanismProperty("ENVIRONMENT", "").Should().Be("azure");
178+
mongoConnection.Credential.GetMechanismProperty("prop", "").Should().Be("ab,cd,ef,jh");
179+
mongoConnection.Credential.GetMechanismProperty("TOKEN_RESOURCE", "").Should().Be("mongodb://test-cluster");
180+
mongoConnection.Credential.GetMechanismProperty("ANOTHER", "").Should().Be("test");
181+
}
158182
}
159183
}

0 commit comments

Comments
 (0)