14
14
*/
15
15
16
16
using System ;
17
- using System . Linq ;
18
17
using System . Security . Cryptography . X509Certificates ;
19
18
using FluentAssertions ;
20
- using MongoDB . Bson ;
21
- using MongoDB . Driver . Core . Clusters . ServerSelectors ;
22
- using MongoDB . Driver . Core . Misc ;
23
19
using MongoDB . Driver . Core . TestHelpers . XunitExtensions ;
24
20
using MongoDB . TestHelpers . XunitExtensions ;
25
21
using Xunit ;
@@ -30,64 +26,83 @@ namespace MongoDB.Driver.Tests;
30
26
[ Trait ( "Category" , "X509" ) ]
31
27
public class X509Tests
32
28
{
33
- [ Theory ]
34
- [ ParameterAttributeData ]
35
- public void Authentication_succeeds_with_MONGODB_X509_mechanism (
36
- [ Values ( false , true ) ] bool async )
37
- {
38
- RequireEnvironment . Check ( ) . EnvironmentVariable ( "MONGO_X509_CLIENT_CERTIFICATE_PATH" , isDefined : true ) ;
39
- RequireEnvironment . Check ( ) . EnvironmentVariable ( "MONGO_X509_CLIENT_CERTIFICATE_PASSWORD" , isDefined : true ) ;
40
- RequireServer . Check ( ) . Tls ( required : true ) ;
41
-
42
- var pathToClientCertificate = Environment . GetEnvironmentVariable ( "MONGO_X509_CLIENT_CERTIFICATE_PATH" ) ;
43
- var password = Environment . GetEnvironmentVariable ( "MONGO_X509_CLIENT_CERTIFICATE_PASSWORD" ) ;
44
- var clientCertificate = new X509Certificate2 ( pathToClientCertificate , password ) ;
45
-
46
- var settings = DriverTestConfiguration . GetClientSettings ( ) . Clone ( ) ;
47
- settings . Credential = MongoCredential . CreateMongoX509Credential ( ) ;
48
- settings . SslSettings = settings . SslSettings . Clone ( ) ;
49
- settings . SslSettings . ClientCertificates = new [ ] { clientCertificate } ;
50
-
51
- AssertAuthenticationSucceeds ( settings , async , speculativeAuthenticatationShouldSucceedIfPossible : true) ;
52
- }
53
-
54
- private void AssertAuthenticationSucceeds (
55
- MongoClientSettings settings ,
56
- bool async ,
57
- bool speculativeAuthenticatationShouldSucceedIfPossible = true )
58
- {
59
- // If we don't use a DisposableClient, the second run of AuthenticationSucceedsWithMongoDB_X509_mechanism
60
- // will fail because the backing Cluster's connections will be associated with a dropped user
61
- using ( var client = DriverTestConfiguration . CreateMongoClient ( settings ) )
62
- {
63
- // The first command executed with the MongoClient triggers either the sync or async variation of the
64
- // MongoClient's IAuthenticator
65
- if ( async)
66
- {
67
- _ = client . ListDatabaseNamesAsync ( ) . GetAwaiter ( ) . GetResult ( ) . ToList ( ) ;
68
- }
69
- else
70
- {
71
- _ = client . ListDatabaseNames ( ) . ToList ( ) ;
72
- }
73
- if ( Feature . SpeculativeAuthentication . IsSupported ( CoreTestConfiguration . MaxWireVersion ) &&
74
- speculativeAuthenticatationShouldSucceedIfPossible )
75
- {
76
- var serverSelector = new ReadPreferenceServerSelector ( settings . ReadPreference ) ;
77
- var server = client. GetClusterInternal( ) . SelectServer( OperationContext . NoTimeout , serverSelector ) ;
78
- var channel = server . GetChannel ( OperationContext . NoTimeout ) ;
79
- var helloResult = channel . ConnectionDescription . HelloResult ;
80
- helloResult. SpeculativeAuthenticate . Should ( ) . NotBeNull ( ) ;
81
- }
82
- }
83
- }
84
-
85
- private string GetRfc2253FormattedUsernameFromX509ClientCertificate( X509Certificate2 certificate )
86
- {
87
- var distinguishedName = certificate. SubjectName . Name ;
88
- // Authentication will fail if we don't remove the delimiting spaces, even if we add the username WITH the
89
- // delimiting spaces.
90
- var nameWithoutDelimitingSpaces = string . Join ( "," , distinguishedName . Split ( ',' ) . Select ( s => s . Trim ( ) ) ) ;
91
- return nameWithoutDelimitingSpaces. Replace ( "S=" , "ST=" ) ;
92
- }
29
+ const string MONGODB_X509_CLIENT_CERTIFICATE_PATH = "MONGO_X509_CLIENT_CERTIFICATE_PATH" ;
30
+ const string MONGODB_X509_CLIENT_CERTIFICATE_PASSWORD = "MONGO_X509_CLIENT_CERTIFICATE_PASSWORD" ;
31
+
32
+ const string MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PATH = "MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PATH" ;
33
+ const string MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PASSWORD = "MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PASSWORD" ;
34
+
35
+ [ Fact ]
36
+ public void Authentication_succeeds_with_MONGODB_X509_mechanism ( )
37
+ {
38
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PATH , isDefined : true ) ;
39
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PASSWORD , isDefined : true ) ;
40
+ RequireServer . Check ( ) . Tls ( required : true ) ;
41
+
42
+ var pathToClientCertificate = Environment . GetEnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PATH ) ;
43
+ var password = Environment . GetEnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PASSWORD ) ;
44
+ var clientCertificate = new X509Certificate2 ( pathToClientCertificate , password ) ;
45
+
46
+ var settings = DriverTestConfiguration . GetClientSettings ( ) . Clone ( ) ;
47
+ //settings.Credential = MongoCredential.CreateMongoX509Credential();
48
+ settings . SslSettings = settings . SslSettings . Clone ( ) ;
49
+ settings . SslSettings . ClientCertificates = [ clientCertificate ] ;
50
+
51
+ AssertAuthenticationSucceeds ( settings ) ;
52
+ }
53
+
54
+ [ Fact ]
55
+ public void Authentication_fails_with_MONGODB_X509_mechanism_when_username_is_wrong ( )
56
+ {
57
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PATH , isDefined : true ) ;
58
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PASSWORD , isDefined : true ) ;
59
+ RequireServer . Check ( ) . Tls ( required : true ) ;
60
+
61
+ var pathToClientCertificate = Environment . GetEnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PATH ) ;
62
+ var password = Environment . GetEnvironmentVariable ( MONGODB_X509_CLIENT_CERTIFICATE_PASSWORD ) ;
63
+ var clientCertificate = new X509Certificate2 ( pathToClientCertificate , password ) ;
64
+
65
+ var settings = DriverTestConfiguration . GetClientSettings ( ) . Clone ( ) ;
66
+ settings . Credential = MongoCredential . CreateMongoX509Credential ( "wrong_username" ) ;
67
+ settings . SslSettings = settings . SslSettings . Clone ( ) ;
68
+ settings . SslSettings . ClientCertificates = [ clientCertificate ] ;
69
+
70
+ AssertAuthenticationFails ( settings ) ;
71
+ }
72
+
73
+ [ Fact ]
74
+ public void Authentication_fails_with_MONGODB_X509_mechanism_when_user_is_not_in_database ( )
75
+ {
76
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PATH , isDefined : true ) ;
77
+ RequireEnvironment . Check ( ) . EnvironmentVariable ( MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PASSWORD , isDefined : true ) ;
78
+ RequireServer . Check ( ) . Tls ( required : true ) ;
79
+
80
+ var pathToClientCertificate = Environment . GetEnvironmentVariable ( MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PATH ) ;
81
+ var password = Environment . GetEnvironmentVariable ( MONGO_X509_CLIENT_NO_USER_CERTIFICATE_PASSWORD ) ;
82
+ var clientCertificate = new X509Certificate2 ( pathToClientCertificate , password ) ;
83
+
84
+ var settings = DriverTestConfiguration . GetClientSettings ( ) . Clone ( ) ;
85
+ //settings.Credential = MongoCredential.CreateMongoX509Credential();
86
+ settings . SslSettings = settings . SslSettings . Clone ( ) ;
87
+ settings . SslSettings . ClientCertificates = [ clientCertificate ] ;
88
+
89
+ AssertAuthenticationFails ( settings ) ;
90
+ }
91
+
92
+ private void AssertAuthenticationSucceeds ( MongoClientSettings settings )
93
+ {
94
+ using var client = DriverTestConfiguration . CreateMongoClient ( settings ) ;
95
+ _ = client . ListDatabaseNames ( ) . ToList ( ) ;
96
+ }
97
+
98
+ private void AssertAuthenticationFails ( MongoClientSettings settings )
99
+ {
100
+ using var client = DriverTestConfiguration . CreateMongoClient ( settings ) ;
101
+ var exception = Record . Exception ( ( ) => client . ListDatabaseNames ( ) . ToList ( ) ) ;
102
+ exception . Should ( ) . BeOfType < MongoAuthenticationException > ( ) ;
103
+
104
+ // var innerException = exception.InnerException;
105
+ // innerException.Should().BeOfType<MongoCommandException>();
106
+ // innerException.Message.Should().Contain("Could not find user");
107
+ }
93
108
}
0 commit comments