@@ -44,14 +44,32 @@ RequestProcessor getRequestProcessor() {
4444 * @return a new Builder instance ready to configure
4545 */
4646 public static Builder newBuilder (String domain , String clientId , String clientSecret ) {
47- return new Builder (domain , clientId , clientSecret );
47+ Validate .notNull (domain , "domain must not be null" );
48+ return new Builder (clientId , clientSecret ).withDomain (domain );
49+ }
50+
51+ /**
52+ * Create a new {@link Builder} instance to configure the {@link AuthenticationController} response type and algorithm used on the verification.
53+ * By default it will request response type 'code' and later perform the Code Exchange, but if the response type is changed to 'token' it will handle
54+ * the Implicit Grant using the HS256 algorithm with the Client Secret as secret.
55+ *
56+ * @param domainResolver the Auth0 domain resolver function
57+ * @param clientId the Auth0 application's client id
58+ * @param clientSecret the Auth0 application's client secret
59+ * @return a new Builder instance ready to configure
60+ */
61+ public static Builder newBuilder (DomainResolver domainResolver ,
62+ String clientId ,
63+ String clientSecret ) {
64+ Validate .notNull (domainResolver , "domainResolver must not be null" );
65+ return new Builder (clientId , clientSecret ).withDomainResolver (domainResolver );
4866 }
4967
5068
5169 public static class Builder {
5270 private static final String RESPONSE_TYPE_CODE = "code" ;
5371
54- private final String domain ;
72+ private String domain ;
5573 private final String clientId ;
5674 private final String clientSecret ;
5775 private String responseType ;
@@ -63,6 +81,7 @@ public static class Builder {
6381 private String invitation ;
6482 private HttpOptions httpOptions ;
6583 private String cookiePath ;
84+ private DomainResolver domainResolver ;
6685
6786 Builder (String domain , String clientId , String clientSecret ) {
6887 Validate .notNull (domain );
@@ -76,6 +95,54 @@ public static class Builder {
7695 this .useLegacySameSiteCookie = true ;
7796 }
7897
98+ Builder (String clientId , String clientSecret ) {
99+ if (clientId == null ) {
100+ throw new IllegalArgumentException ("clientId cannot be null" );
101+ }
102+ if (clientSecret == null ) {
103+ throw new IllegalArgumentException ("clientSecret cannot be null" );
104+ }
105+
106+ this .clientId = clientId ;
107+ this .clientSecret = clientSecret ;
108+ this .responseType = RESPONSE_TYPE_CODE ;
109+ this .useLegacySameSiteCookie = true ;
110+ }
111+
112+ /**
113+ * Sets the Auth0 domain to use.
114+ * Note: The `domainResolver` must be null when setting the `domain`.
115+ *
116+ * @param domain the Auth0 domain to use, a non-null value.
117+ * @return this same builder instance.
118+ * @throws IllegalStateException if `domainResolver` is already set.
119+ */
120+ public Builder withDomain (String domain ) {
121+ if (this .domainResolver != null ) {
122+ throw new IllegalStateException ("Cannot specify both 'domain' and 'domainResolver'." );
123+ }
124+ Validate .notNull (domain , "domain must not be null" );
125+ this .domain = domain ;
126+ return this ;
127+ }
128+
129+ /**
130+ * Sets the Auth0 domain resolver function to use.
131+ * Note: The `domain` must be null when setting the `domainResolver`.
132+ *
133+ * @param domainResolver the domain resolver function to use, a non-null value.
134+ * @return this same builder instance.
135+ * @throws IllegalStateException if `domain` is already set.
136+ */
137+ public Builder withDomainResolver (DomainResolver domainResolver ) {
138+ if (this .domain != null ) {
139+ throw new IllegalStateException ("Cannot specify both 'domain' and 'domainResolver'." );
140+ }
141+ Validate .notNull (domainResolver , "domainResolver must not be null" );
142+ this .domainResolver = domainResolver ;
143+ return this ;
144+ }
145+
79146 /**
80147 * Customize certain aspects of the underlying HTTP client networking library, such as timeouts and proxy configuration.
81148 *
@@ -196,29 +263,18 @@ public Builder withInvitation(String invitation) {
196263 * @throws UnsupportedOperationException if the Implicit Grant is chosen and the environment doesn't support UTF-8 encoding.
197264 */
198265 public AuthenticationController build () throws UnsupportedOperationException {
199- AuthAPI apiClient = createAPIClient (domain , clientId , clientSecret , httpOptions );
200- setupTelemetry (apiClient );
201-
202- final boolean expectedAlgorithmIsExplicitlySetAndAsymmetric = jwkProvider != null ;
203- final SignatureVerifier signatureVerifier ;
204- if (expectedAlgorithmIsExplicitlySetAndAsymmetric ) {
205- signatureVerifier = new AsymmetricSignatureVerifier (jwkProvider );
206- } else if (responseType .contains (RESPONSE_TYPE_CODE )) {
207- // Old behavior: To maintain backwards-compatibility when
208- // no explicit algorithm is set by the user, we
209- // must skip ID Token signature check.
210- signatureVerifier = new AlgorithmNameVerifier ();
211- } else {
212- signatureVerifier = new SymmetricSignatureVerifier (clientSecret );
213- }
266+ validateDomainConfiguration ();
267+
268+ DomainProvider domainProvider =
269+ domain != null
270+ ? new StaticDomainProvider (domain )
271+ : new ResolverDomainProvider (domainResolver );
214272
215- String issuer = getIssuer (domain );
216- IdTokenVerifier .Options verifyOptions = createIdTokenVerificationOptions (issuer , clientId , signatureVerifier );
217- verifyOptions .setClockSkew (clockSkew );
218- verifyOptions .setMaxAge (authenticationMaxAge );
219- verifyOptions .setOrganization (this .organization );
273+ SignatureVerifier signatureVerifier = buildSignatureVerifier ();
220274
221- RequestProcessor processor = new RequestProcessor .Builder (apiClient , responseType , verifyOptions )
275+ RequestProcessor processor = new RequestProcessor .Builder (domainProvider , responseType , clientId , clientSecret , httpOptions , signatureVerifier )
276+ .withClockSkew (clockSkew )
277+ .withAuthenticationMaxAge (authenticationMaxAge )
222278 .withLegacySameSiteCookie (useLegacySameSiteCookie )
223279 .withOrganization (organization )
224280 .withInvitation (invitation )
@@ -228,6 +284,25 @@ public AuthenticationController build() throws UnsupportedOperationException {
228284 return new AuthenticationController (processor );
229285 }
230286
287+ private void validateDomainConfiguration () {
288+ if (domain == null && domainResolver == null ) {
289+ throw new IllegalStateException ("Either domain or domainResolver must be provided." );
290+ }
291+ if (domain != null && domainResolver != null ) {
292+ throw new IllegalStateException ("Cannot specify both domain and domainResolver." );
293+ }
294+ }
295+
296+ private SignatureVerifier buildSignatureVerifier () {
297+ if (jwkProvider != null ) {
298+ return new AsymmetricSignatureVerifier (jwkProvider );
299+ }
300+ if (responseType .contains (RESPONSE_TYPE_CODE )) {
301+ return new AlgorithmNameVerifier (); // legacy behavior
302+ }
303+ return new SymmetricSignatureVerifier (clientSecret );
304+ }
305+
231306 @ VisibleForTesting
232307 IdTokenVerifier .Options createIdTokenVerificationOptions (String issuer , String audience , SignatureVerifier signatureVerifier ) {
233308 return new IdTokenVerifier .Options (issuer , audience , signatureVerifier );
@@ -243,6 +318,7 @@ AuthAPI createAPIClient(String domain, String clientId, String clientSecret, Htt
243318
244319 @ VisibleForTesting
245320 void setupTelemetry (AuthAPI client ) {
321+ if (client == null ) return ;
246322 Telemetry telemetry = new Telemetry ("auth0-java-mvc-common" , obtainPackageVersion ());
247323 client .setTelemetry (telemetry );
248324 }
@@ -265,22 +341,22 @@ private String getIssuer(String domain) {
265341 }
266342 }
267343
268- /**
269- * Whether to enable or not the HTTP Logger for every Request and Response.
270- * Enabling this can expose sensitive information.
271- *
272- * @param enabled whether to enable the HTTP logger or not.
273- */
274- public void setLoggingEnabled (boolean enabled ) {
275- requestProcessor .getClient ().setLoggingEnabled (enabled );
276- }
277-
278- /**
279- * Disable sending the Telemetry header on every request to the Auth0 API
280- */
281- public void doNotSendTelemetry () {
282- requestProcessor .getClient ().doNotSendTelemetry ();
283- }
344+ // /**
345+ // * Whether to enable or not the HTTP Logger for every Request and Response.
346+ // * Enabling this can expose sensitive information.
347+ // *
348+ // * @param enabled whether to enable the HTTP logger or not.
349+ // */
350+ // public void setLoggingEnabled(boolean enabled) {
351+ // requestProcessor.getClient().setLoggingEnabled(enabled);
352+ // }
353+ //
354+ // /**
355+ // * Disable sending the Telemetry header on every request to the Auth0 API
356+ // */
357+ // public void doNotSendTelemetry() {
358+ // requestProcessor.getClient().doNotSendTelemetry();
359+ // }
284360
285361 /**
286362 * Process a request to obtain a set of {@link Tokens} that represent successful authentication or authorization.
0 commit comments