25
25
import java .util .Arrays ;
26
26
import java .util .Collections ;
27
27
import java .util .HashMap ;
28
+ import java .util .List ;
28
29
import java .util .Map ;
29
30
import java .util .Objects ;
30
31
@@ -187,7 +188,8 @@ public final class MongoCredential {
187
188
* The provider name. The value must be a string.
188
189
* <p>
189
190
* If this is provided,
190
- * {@link MongoCredential#OIDC_CALLBACK_KEY}
191
+ * {@link MongoCredential#OIDC_CALLBACK_KEY} and
192
+ * {@link MongoCredential#OIDC_HUMAN_CALLBACK_KEY}
191
193
* must not be provided.
192
194
*
193
195
* @see #createOidcCredential(String)
@@ -197,17 +199,60 @@ public final class MongoCredential {
197
199
198
200
/**
199
201
* This callback is invoked when the OIDC-based authenticator requests
200
- * tokens from the identity provider. The type of the value must be
201
- * {@link OidcRequestCallback}.
202
+ * a token. The type of the value must be {@link OidcCallback}.
203
+ * {@link IdpInfo} will not be supplied to the callback,
204
+ * and a {@linkplain OidcCallbackResult#getRefreshToken() refresh token}
205
+ * must not be returned by the callback.
202
206
* <p>
203
207
* If this is provided, {@link MongoCredential#PROVIDER_NAME_KEY}
208
+ * and {@link MongoCredential#OIDC_HUMAN_CALLBACK_KEY}
204
209
* must not be provided.
205
210
*
206
211
* @see #createOidcCredential(String)
207
212
* @since 4.10
208
213
*/
209
214
public static final String OIDC_CALLBACK_KEY = "OIDC_CALLBACK" ;
210
215
216
+ /**
217
+ * This callback is invoked when the OIDC-based authenticator requests
218
+ * a token from the identity provider (IDP) using the IDP information
219
+ * from the MongoDB server. The type of the value must be
220
+ * {@link OidcCallback}.
221
+ * <p>
222
+ * If this is provided, {@link MongoCredential#PROVIDER_NAME_KEY}
223
+ * and {@link MongoCredential#OIDC_CALLBACK_KEY}
224
+ * must not be provided.
225
+ *
226
+ * @see #createOidcCredential(String)
227
+ * @since 4.10
228
+ */
229
+ public static final String OIDC_HUMAN_CALLBACK_KEY = "OIDC_HUMAN_CALLBACK" ;
230
+
231
+
232
+ /**
233
+ * Mechanism key for a list of allowed hostnames or ip-addresses for MongoDB connections. Ports must be excluded.
234
+ * The hostnames may include a leading "*." wildcard, which allows for matching (potentially nested) subdomains.
235
+ * When MONGODB-OIDC authentication is attempted against a hostname that does not match any of list of allowed hosts
236
+ * the driver will raise an error. The type of the value must be {@code List<String>}.
237
+ *
238
+ * @see MongoCredential#DEFAULT_ALLOWED_HOSTS
239
+ * @see #createOidcCredential(String)
240
+ * @since 4.10
241
+ */
242
+ public static final String ALLOWED_HOSTS_KEY = "ALLOWED_HOSTS" ;
243
+
244
+ /**
245
+ * The list of allowed hosts that will be used if no
246
+ * {@link MongoCredential#ALLOWED_HOSTS_KEY} value is supplied.
247
+ * The default allowed hosts are:
248
+ * {@code "*.mongodb.net", "*.mongodb-qa.net", "*.mongodb-dev.net", "*.mongodbgov.net", "localhost", "127.0.0.1", "::1"}
249
+ *
250
+ * @see #createOidcCredential(String)
251
+ * @since 4.10
252
+ */
253
+ public static final List <String > DEFAULT_ALLOWED_HOSTS = Collections .unmodifiableList (Arrays .asList (
254
+ "*.mongodb.net" , "*.mongodb-qa.net" , "*.mongodb-dev.net" , "*.mongodbgov.net" , "localhost" , "127.0.0.1" , "::1" ));
255
+
211
256
/**
212
257
* Creates a MongoCredential instance with an unspecified mechanism. The client will negotiate the best mechanism based on the
213
258
* version of the server that the client is authenticating to.
@@ -365,6 +410,8 @@ public static MongoCredential createAwsCredential(@Nullable final String userNam
365
410
* @see #withMechanismProperty(String, Object)
366
411
* @see #PROVIDER_NAME_KEY
367
412
* @see #OIDC_CALLBACK_KEY
413
+ * @see #OIDC_HUMAN_CALLBACK_KEY
414
+ * @see #ALLOWED_HOSTS_KEY
368
415
* @mongodb.server.release 7.0
369
416
*/
370
417
public static MongoCredential createOidcCredential (@ Nullable final String userName ) {
@@ -593,10 +640,15 @@ public String toString() {
593
640
}
594
641
595
642
/**
596
- * The context for the {@link OidcRequestCallback #onRequest(OidcRequestContext ) OIDC request callback}.
643
+ * The context for the {@link OidcCallback #onRequest(OidcCallbackContext ) OIDC request callback}.
597
644
*/
598
645
@ Evolving
599
- public interface OidcRequestContext {
646
+ public interface OidcCallbackContext {
647
+ /**
648
+ * @return The OIDC Identity Provider's configuration that can be used to acquire an Access Token.
649
+ */
650
+ @ Nullable
651
+ IdpInfo getIdpInfo ();
600
652
601
653
/**
602
654
* @return The timeout that this callback must complete within.
@@ -607,6 +659,12 @@ public interface OidcRequestContext {
607
659
* @return The OIDC callback API version. Currently, version 1.
608
660
*/
609
661
int getVersion ();
662
+
663
+ /**
664
+ * @return The OIDC Refresh token supplied by a prior callback invocation.
665
+ */
666
+ @ Nullable
667
+ String getRefreshToken ();
610
668
}
611
669
612
670
/**
@@ -616,27 +674,76 @@ public interface OidcRequestContext {
616
674
* It does not have to be thread-safe, unless it is provided to multiple
617
675
* MongoClients.
618
676
*/
619
- public interface OidcRequestCallback {
677
+ public interface OidcCallback {
620
678
/**
621
679
* @param context The context.
622
680
* @return The response produced by an OIDC Identity Provider
623
681
*/
624
- RequestCallbackResult onRequest (OidcRequestContext context );
682
+ OidcCallbackResult onRequest (OidcCallbackContext context );
683
+ }
684
+
685
+ /**
686
+ * The OIDC Identity Provider's configuration that can be used to acquire an Access Token.
687
+ */
688
+ @ Evolving
689
+ public interface IdpInfo {
690
+ /**
691
+ * @return URL which describes the Authorization Server. This identifier is the
692
+ * iss of provided access tokens, and is viable for RFC8414 metadata
693
+ * discovery and RFC9207 identification.
694
+ */
695
+ String getIssuer ();
696
+
697
+ /**
698
+ * @return Unique client ID for this OIDC client.
699
+ */
700
+ String getClientId ();
701
+
702
+ /**
703
+ * @return Additional scopes to request from Identity Provider. Immutable.
704
+ */
705
+ List <String > getRequestScopes ();
625
706
}
626
707
627
708
/**
628
709
* The response produced by an OIDC Identity Provider.
629
710
*/
630
- public static final class RequestCallbackResult {
711
+ public static final class OidcCallbackResult {
631
712
632
713
private final String accessToken ;
633
714
715
+ private final Duration expiresIn ;
716
+
717
+ @ Nullable
718
+ private final String refreshToken ;
719
+
720
+ /**
721
+ * @param accessToken The OIDC access token.
722
+ * @param expiresIn Time until the access token expires.
723
+ * A {@linkplain Duration#isZero() zero-length} duration
724
+ * means that the access token does not expire.
725
+ */
726
+ public OidcCallbackResult (final String accessToken , final Duration expiresIn ) {
727
+ this (accessToken , expiresIn , null );
728
+ }
729
+
634
730
/**
635
- * @param accessToken The OIDC access token
731
+ * @param accessToken The OIDC access token.
732
+ * @param expiresIn Time until the access token expires.
733
+ * A {@linkplain Duration#isZero() zero-length} duration
734
+ * means that the access token does not expire.
735
+ * @param refreshToken The refresh token. If null, refresh will not be attempted.
636
736
*/
637
- public RequestCallbackResult (final String accessToken ) {
737
+ public OidcCallbackResult (final String accessToken , final Duration expiresIn ,
738
+ @ Nullable final String refreshToken ) {
638
739
notNull ("accessToken" , accessToken );
740
+ notNull ("expiresIn" , expiresIn );
741
+ if (expiresIn .isNegative ()) {
742
+ throw new IllegalArgumentException ("expiresIn must not be a negative value" );
743
+ }
639
744
this .accessToken = accessToken ;
745
+ this .expiresIn = expiresIn ;
746
+ this .refreshToken = refreshToken ;
640
747
}
641
748
642
749
/**
@@ -645,5 +752,13 @@ public RequestCallbackResult(final String accessToken) {
645
752
public String getAccessToken () {
646
753
return accessToken ;
647
754
}
755
+
756
+ /**
757
+ * @return The OIDC refresh token. If null, refresh will not be attempted.
758
+ */
759
+ @ Nullable
760
+ public String getRefreshToken () {
761
+ return refreshToken ;
762
+ }
648
763
}
649
764
}
0 commit comments