@@ -54,7 +54,8 @@ public class AuthAPI {
5454 private static final String KEY_OTP = "otp" ;
5555 private static final String KEY_REALM = "realm" ;
5656 private static final String KEY_MFA_TOKEN = "mfa_token" ;
57-
57+ private static final String KEY_CLIENT_ASSERTION = "client_assertion" ;
58+ private static final String KEY_CLIENT_ASSERTION_TYPE = "client_assertion_type" ;
5859 private static final String PATH_OAUTH = "oauth" ;
5960 private static final String PATH_TOKEN = "token" ;
6061 private static final String PATH_DBCONNECTIONS = "dbconnections" ;
@@ -65,6 +66,7 @@ public class AuthAPI {
6566 private final Auth0HttpClient client ;
6667 private final String clientId ;
6768 private final String clientSecret ;
69+ private final ClientAssertionSigner clientAssertionSigner ;
6870 private final HttpUrl baseUrl ;
6971
7072 /**
@@ -83,7 +85,7 @@ public class AuthAPI {
8385 @ Deprecated
8486 @ SuppressWarnings ("deprecation" )
8587 public AuthAPI (String domain , String clientId , String clientSecret , com .auth0 .client .HttpOptions options ) {
86- this (domain , clientId , clientSecret , buildNetworkingClient (options ));
88+ this (domain , clientId , clientSecret , null , buildNetworkingClient (options ));
8789 }
8890
8991 /**
@@ -110,7 +112,20 @@ public AuthAPI(String domain, String clientId, String clientSecret) {
110112 * @return a Builder for further configuration.
111113 */
112114 public static AuthAPI .Builder newBuilder (String domain , String clientId , String clientSecret ) {
113- return new AuthAPI .Builder (domain , clientId , clientSecret );
115+ return new AuthAPI .Builder (domain , clientId ).withClientSecret (clientSecret );
116+ }
117+
118+ /**
119+ * Initialize a new {@link Builder} to configure and create an instance. Use this to construct an instance
120+ * with a client assertion signer used in place of a client secret when calling token APIs.
121+ *
122+ * @param domain the tenant's domain. Must be a non-null valid HTTPS URL.
123+ * @param clientId the application's client ID.
124+ * @param clientAssertionSigner the {@code ClientAssertionSigner} used to create the signed client assertion.
125+ * @return a Builder for further configuration.
126+ */
127+ public static AuthAPI .Builder newBuilder (String domain , String clientId , ClientAssertionSigner clientAssertionSigner ) {
128+ return new AuthAPI .Builder (domain , clientId ).withClientAssertionSigner (clientAssertionSigner );
114129 }
115130
116131 /**
@@ -124,7 +139,7 @@ public static AuthAPI.Builder newBuilder(String domain, String clientId) {
124139 return new AuthAPI .Builder (domain , clientId );
125140 }
126141
127- private AuthAPI (String domain , String clientId , String clientSecret , Auth0HttpClient httpClient ) {
142+ private AuthAPI (String domain , String clientId , String clientSecret , ClientAssertionSigner clientAssertionSigner , Auth0HttpClient httpClient ) {
128143 Asserts .assertNotNull (domain , "domain" );
129144 Asserts .assertNotNull (clientId , "client id" );
130145 Asserts .assertNotNull (httpClient , "Http client" );
@@ -135,9 +150,11 @@ private AuthAPI(String domain, String clientId, String clientSecret, Auth0HttpCl
135150 }
136151 this .clientId = clientId ;
137152 this .clientSecret = clientSecret ;
153+ this .clientAssertionSigner = clientAssertionSigner ;
138154 this .client = httpClient ;
139-
140155 }
156+
157+
141158 /**
142159 * Given a set of options, it creates a new instance of the {@link OkHttpClient}
143160 * configuring them according to their availability.
@@ -487,7 +504,7 @@ public TokenRequest login(String emailOrUsername, char[] password) {
487504 request .addParameter (KEY_GRANT_TYPE , "password" );
488505 request .addParameter (KEY_USERNAME , emailOrUsername );
489506 request .addParameter (KEY_PASSWORD , password );
490- addSecret (request , true );
507+ addClientAuthentication (request , true );
491508 return request ;
492509 }
493510
@@ -555,7 +572,7 @@ public TokenRequest login(String emailOrUsername, char[] password, String realm)
555572 request .addParameter (KEY_USERNAME , emailOrUsername );
556573 request .addParameter (KEY_PASSWORD , password );
557574 request .addParameter (KEY_REALM , realm );
558- addSecret (request , true );
575+ addClientAuthentication (request , true );
559576 return request ;
560577 }
561578
@@ -597,7 +614,7 @@ public TokenRequest exchangePasswordlessOtp(String emailOrPhone, String realm, c
597614 request .addParameter (KEY_USERNAME , emailOrPhone );
598615 request .addParameter (KEY_REALM , realm );
599616 request .addParameter (KEY_OTP , otp );
600- addSecret (request , false );
617+ addClientAuthentication (request , false );
601618 return request ;
602619 }
603620
@@ -629,7 +646,7 @@ public TokenRequest requestToken(String audience) {
629646 request .addParameter (KEY_CLIENT_ID , clientId );
630647 request .addParameter (KEY_GRANT_TYPE , "client_credentials" );
631648 request .addParameter (KEY_AUDIENCE , audience );
632- addSecret (request , true );
649+ addClientAuthentication (request , true );
633650 return request ;
634651 }
635652
@@ -663,7 +680,7 @@ public Request<Void> revokeToken(String refreshToken) {
663680 VoidRequest request = new VoidRequest (client , null , url , HttpMethod .POST );
664681 request .addParameter (KEY_CLIENT_ID , clientId );
665682 request .addParameter (KEY_TOKEN , refreshToken );
666- addSecret (request , false );
683+ addClientAuthentication (request , false );
667684 return request ;
668685 }
669686
@@ -696,7 +713,7 @@ public TokenRequest renewAuth(String refreshToken) {
696713 request .addParameter (KEY_CLIENT_ID , clientId );
697714 request .addParameter (KEY_GRANT_TYPE , "refresh_token" );
698715 request .addParameter (KEY_REFRESH_TOKEN , refreshToken );
699- addSecret (request , false );
716+ addClientAuthentication (request , false );
700717 return request ;
701718 }
702719
@@ -816,7 +833,7 @@ public BaseRequest<PasswordlessEmailResponse> startPasswordlessEmailFlow(String
816833 request .addParameter (KEY_CONNECTION , "email" );
817834 request .addParameter (KEY_EMAIL , email );
818835 request .addParameter ("send" , type .getType ());
819- addSecret (request , false );
836+ addClientAuthentication (request , false );
820837 return request ;
821838 }
822839
@@ -857,7 +874,7 @@ public BaseRequest<PasswordlessSmsResponse> startPasswordlessSmsFlow(String phon
857874 request .addParameter (KEY_CLIENT_ID , clientId );
858875 request .addParameter (KEY_CONNECTION , "sms" );
859876 request .addParameter ("phone_number" , phoneNumber );
860- addSecret (request , false );
877+ addClientAuthentication (request , false );
861878 return request ;
862879 }
863880
@@ -892,7 +909,7 @@ public TokenRequest exchangeMfaOtp(String mfaToken, char[] otp) {
892909 request .addParameter (KEY_GRANT_TYPE , "http://auth0.com/oauth/grant-type/mfa-otp" );
893910 request .addParameter (KEY_MFA_TOKEN , mfaToken );
894911 request .addParameter (KEY_OTP , otp );
895- addSecret (request , false );
912+ addClientAuthentication (request , false );
896913 return request ;
897914 }
898915
@@ -933,7 +950,7 @@ public TokenRequest exchangeMfaOob(String mfaToken, char[] oobCode, char[] bindi
933950 request .addParameter ("binding_code" , bindingCode );
934951 }
935952
936- addSecret (request , false );
953+ addClientAuthentication (request , false );
937954 return request ;
938955 }
939956
@@ -968,7 +985,7 @@ public TokenRequest exchangeMfaRecoveryCode(String mfaToken, char[] recoveryCode
968985 request .addParameter (KEY_MFA_TOKEN , mfaToken );
969986 request .addParameter ("recovery_code" , recoveryCode );
970987
971- addSecret (request , false );
988+ addClientAuthentication (request , false );
972989 return request ;
973990 }
974991
@@ -1008,7 +1025,7 @@ public Request<MfaChallengeResponse> mfaChallengeRequest(String mfaToken, String
10081025
10091026 request .addParameter (KEY_MFA_TOKEN , mfaToken );
10101027 request .addParameter (KEY_CLIENT_ID , clientId );
1011- addSecret (request , false );
1028+ addClientAuthentication (request , false );
10121029 if (Objects .nonNull (challengeType )) {
10131030 request .addParameter ("challenge_type" , challengeType );
10141031 }
@@ -1052,7 +1069,7 @@ public Request<CreatedOtpResponse> addOtpAuthenticator(String mfaToken) {
10521069
10531070 request .addParameter ("authenticator_types" , Collections .singletonList ("otp" ));
10541071 request .addParameter (KEY_CLIENT_ID , clientId );
1055- addSecret (request , false );
1072+ addClientAuthentication (request , false );
10561073 request .addHeader ("Authorization" , "Bearer " + mfaToken );
10571074 return request ;
10581075 }
@@ -1098,7 +1115,7 @@ public Request<CreatedOobResponse> addOobAuthenticator(String mfaToken, List<Str
10981115 if (phoneNumber != null ) {
10991116 request .addParameter ("phone_number" , phoneNumber );
11001117 }
1101- addSecret (request , false );
1118+ addClientAuthentication (request , false );
11021119 request .addHeader ("Authorization" , "Bearer " + mfaToken );
11031120 return request ;
11041121 }
@@ -1149,7 +1166,7 @@ private TokenRequest exchangeCode(String code, String redirectUri, boolean secre
11491166 request .addParameter (KEY_GRANT_TYPE , "authorization_code" );
11501167 request .addParameter ("code" , code );
11511168 request .addParameter ("redirect_uri" , redirectUri );
1152- addSecret (request , secretRequired );
1169+ addClientAuthentication (request , secretRequired );
11531170 return request ;
11541171 }
11551172
@@ -1162,40 +1179,54 @@ private String getTokenUrl() {
11621179 .toString ();
11631180 }
11641181
1165- private void addSecret (BaseRequest <?> request , boolean required ) {
1166- if (required && Objects . isNull (this .clientSecret )) {
1167- throw new IllegalStateException ("A client secret is required for this operation" );
1182+ private void addClientAuthentication (BaseRequest <?> request , boolean required ) {
1183+ if (required && (this .clientSecret == null && this . clientAssertionSigner == null )) {
1184+ throw new IllegalStateException ("A client secret or client assertion signing key is required for this operation" );
11681185 }
1169- if (Objects .nonNull (this .clientSecret )) {
1170- request .addParameter (KEY_CLIENT_SECRET , this .clientSecret );
1186+
1187+ if (Objects .nonNull (this .clientAssertionSigner )) {
1188+ request .addParameter (KEY_CLIENT_ASSERTION , this .clientAssertionSigner .createSignedClientAssertion (clientId , baseUrl .toString (), clientId ));
1189+ request .addParameter (KEY_CLIENT_ASSERTION_TYPE , "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" );
1190+ } else if (Objects .nonNull (this .clientSecret )) {
1191+ request .addParameter (KEY_CLIENT_SECRET , clientSecret );
11711192 }
11721193 }
11731194
1195+
11741196 /**
11751197 * Builder for {@link AuthAPI} API client instances.
11761198 */
11771199 public static class Builder {
11781200 private final String domain ;
11791201 private final String clientId ;
1180- private final String clientSecret ;
1202+ private String clientSecret ;
1203+ private ClientAssertionSigner clientAssertionSigner ;
11811204 private Auth0HttpClient httpClient ;
11821205
1183- /**
1184- * Create a new Builder
1185- * @param domain the domain of the tenant.
1186- * @param clientId the client ID of the Auth0 application.
1187- * @param clientSecret the client secret of the Auth0 application.
1188- */
1189- public Builder (String domain , String clientId , String clientSecret ) {
1206+ public Builder (String domain , String clientId ) {
11901207 this .domain = domain ;
11911208 this .clientId = clientId ;
1209+ this .clientSecret = null ;
1210+ }
1211+
1212+ /**
1213+ * Configure the client with a client secret.
1214+ * @param clientSecret the client secret of your application.
1215+ * @return the builder instance.
1216+ */
1217+ public Builder withClientSecret (String clientSecret ) {
11921218 this .clientSecret = clientSecret ;
1219+ return this ;
11931220 }
11941221
1195- public Builder (String domain , String clientId ) {
1196- this .domain = domain ;
1197- this .clientId = clientId ;
1198- this .clientSecret = null ;
1222+ /**
1223+ * Configure the client with a client assertion signer.
1224+ * @param clientAssertionSigner the client assertion signer to create the signed client assertion.
1225+ * @return the builder instance.
1226+ */
1227+ public Builder withClientAssertionSigner (ClientAssertionSigner clientAssertionSigner ) {
1228+ this .clientAssertionSigner = clientAssertionSigner ;
1229+ return this ;
11991230 }
12001231
12011232 /**
@@ -1214,7 +1245,7 @@ public Builder withHttpClient(Auth0HttpClient httpClient) {
12141245 * @return the configured {@code AuthAPI} instance.
12151246 */
12161247 public AuthAPI build () {
1217- return new AuthAPI (domain , clientId , clientSecret ,
1248+ return new AuthAPI (domain , clientId , clientSecret , clientAssertionSigner ,
12181249 Objects .nonNull (httpClient ) ? httpClient : DefaultHttpClient .newBuilder ().build ());
12191250 }
12201251 }
0 commit comments