2929import static com .mongodb .AuthenticationMechanism .MONGODB_X509 ;
3030import static com .mongodb .AuthenticationMechanism .PLAIN ;
3131import static com .mongodb .AuthenticationMechanism .SCRAM_SHA_1 ;
32+ import static com .mongodb .AuthenticationMechanism .SCRAM_SHA_256 ;
3233import static com .mongodb .assertions .Assertions .notNull ;
3334
3435/**
@@ -148,19 +149,20 @@ public final class MongoCredential {
148149
149150 /**
150151 * Creates a MongoCredential instance with an unspecified mechanism. The client will negotiate the best mechanism based on the
151- * version of the server that the client is authenticating to. If the server version is 3.0 or higher,
152- * the driver will authenticate using the SCRAM-SHA-1 mechanism. Otherwise, the driver will authenticate using the MONGODB_CR
153- * mechanism.
152+ * version of the server that the client is authenticating to.
154153 *
154+ * <p>If the server version is 4.0 or higher, the driver will negotiate with the server preferring the SCRAM-SHA-256 mechanism. 3.x
155+ * servers will authenticate using SCRAM-SHA-1, older servers will authenticate using the MONGODB_CR mechanism.</p>
155156 *
156157 * @param userName the user name
157158 * @param database the database where the user is defined
158159 * @param password the user's password
159160 * @return the credential
160161 *
161162 * @since 2.13
162- * @mongodb.driver.manual core/authentication/#mongodb-cr-authentication MONGODB-CR
163+ * @mongodb.driver.manual core/authentication/#authentication-scram-sha-256 SCRAM-SHA-256
163164 * @mongodb.driver.manual core/authentication/#authentication-scram-sha-1 SCRAM-SHA-1
165+ * @mongodb.driver.manual core/authentication/#mongodb-cr-authentication MONGODB-CR
164166 */
165167 public static MongoCredential createCredential (final String userName , final String database , final char [] password ) {
166168 return new MongoCredential (null , userName , database , password );
@@ -187,6 +189,23 @@ public static MongoCredential createScramSha1Credential(final String userName, f
187189 return new MongoCredential (SCRAM_SHA_1 , userName , source , password );
188190 }
189191
192+ /**
193+ * Creates a MongoCredential instance for the SCRAM-SHA-256 SASL mechanism.
194+ *
195+ * @param userName the non-null user name
196+ * @param source the source where the user is defined.
197+ * @param password the non-null user password
198+ * @return the credential
199+ * @see #createCredential(String, String, char[])
200+ *
201+ * @since 3.8
202+ * @mongodb.server.release 4.0
203+ * @mongodb.driver.manual core/authentication/#authentication-scram-sha-256 SCRAM-SHA-256
204+ */
205+ public static MongoCredential createScramSha256Credential (final String userName , final String source , final char [] password ) {
206+ return new MongoCredential (SCRAM_SHA_256 , userName , source , password );
207+ }
208+
190209 /**
191210 * Creates a MongoCredential instance for the MongoDB Challenge Response protocol. Use this method only if you want to ensure that
192211 * the driver uses the MONGODB_CR mechanism regardless of whether the server you are connecting to supports a more secure
@@ -296,6 +315,20 @@ public <T> MongoCredential withMechanismProperty(final String key, final T value
296315 return new MongoCredential (this , key , value );
297316 }
298317
318+ /**
319+ * Creates a new MongoCredential with the set mechanism. The existing mechanism must be null.
320+ *
321+ * @param mechanism the mechanism to set
322+ * @return the credential
323+ * @since 3.8
324+ */
325+ public MongoCredential withMechanism (final AuthenticationMechanism mechanism ) {
326+ if (this .mechanism != null ) {
327+ throw new IllegalArgumentException ("Mechanism already set" );
328+ }
329+ return new MongoCredential (mechanism , userName , source , password , mechanismProperties );
330+ }
331+
299332 /**
300333 * Constructs a new instance using the given mechanism, userName, source, and password
301334 *
@@ -306,6 +339,11 @@ public <T> MongoCredential withMechanismProperty(final String key, final T value
306339 */
307340 MongoCredential (@ Nullable final AuthenticationMechanism mechanism , @ Nullable final String userName , final String source ,
308341 @ Nullable final char [] password ) {
342+ this (mechanism , userName , source , password , Collections .<String , Object >emptyMap ());
343+ }
344+
345+ MongoCredential (@ Nullable final AuthenticationMechanism mechanism , @ Nullable final String userName , final String source ,
346+ @ Nullable final char [] password , final Map <String , Object > mechanismProperties ) {
309347 if (mechanism != MONGODB_X509 && userName == null ) {
310348 throw new IllegalArgumentException ("username can not be null" );
311349 }
@@ -327,12 +365,13 @@ public <T> MongoCredential withMechanismProperty(final String key, final T value
327365 this .source = notNull ("source" , source );
328366
329367 this .password = password != null ? password .clone () : null ;
330- this .mechanismProperties = Collections . emptyMap ( );
368+ this .mechanismProperties = new HashMap < String , Object >( mechanismProperties );
331369 }
332370
333371 @ SuppressWarnings ("deprecation" )
334372 private boolean mechanismRequiresPassword (@ Nullable final AuthenticationMechanism mechanism ) {
335- return mechanism == PLAIN || mechanism == MONGODB_CR || mechanism == SCRAM_SHA_1 ;
373+ return mechanism == PLAIN || mechanism == MONGODB_CR || mechanism == SCRAM_SHA_1 || mechanism == SCRAM_SHA_256 ;
374+
336375 }
337376
338377 /**
@@ -469,12 +508,12 @@ public int hashCode() {
469508 @ Override
470509 public String toString () {
471510 return "MongoCredential{"
472- + "mechanism=" + mechanism
473- + ", userName='" + userName + '\''
474- + ", source='" + source + '\''
475- + ", password=<hidden>"
476- + ", mechanismProperties=" + mechanismProperties
477- + '}' ;
511+ + "mechanism=" + mechanism
512+ + ", userName='" + userName + '\''
513+ + ", source='" + source + '\''
514+ + ", password=<hidden>"
515+ + ", mechanismProperties=" + mechanismProperties
516+ + '}' ;
478517 }
479518}
480519
0 commit comments