diff --git a/src/main/java/com/auth0/client/auth/AuthAPI.java b/src/main/java/com/auth0/client/auth/AuthAPI.java index acdb3c83..342e70ca 100644 --- a/src/main/java/com/auth0/client/auth/AuthAPI.java +++ b/src/main/java/com/auth0/client/auth/AuthAPI.java @@ -59,6 +59,8 @@ public class AuthAPI { private static final String KEY_CLIENT_ASSERTION_TYPE = "client_assertion_type"; private static final String KEY_SUBJECT_TOKEN = "subject_token"; private static final String KEY_SUBJECT_TOKEN_TYPE = "subject_token_type"; + private static final String KEY_REQUESTED_TOKEN_TYPE = "requested_token_type"; + private static final String KEY_LOGIN_HINT = "login_hint"; private static final String PATH_OAUTH = "oauth"; private static final String PATH_TOKEN = "token"; private static final String PATH_DBCONNECTIONS = "dbconnections"; @@ -840,6 +842,54 @@ public TokenRequest exchangeToken(String subjectToken, String subjectTokenType) return request; } + /** + * Creates a request to exchange an Auth0 refresh token for a federated identity provider's access token + * using the Token Vault grant + * {@code urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token}. + * The connection must have the token vault enabled, and client authentication + * (client secret or client assertion) is required as this must be a private client. + *
+ * {@code
+ * try {
+ * TokenHolder result = authAPI.getTokenForConnection("google-oauth2", refreshToken, "google-user-id")
+ * .execute()
+ * .getBody();
+ * String federatedAccessToken = result.getAccessToken();
+ * } catch (Auth0Exception e) {
+ * //Something happened
+ * }
+ * }
+ *
+ *
+ * @see Token Vault documentation
+ * @param connection the name of the federated connection to obtain an access token for
+ * (for example {@code google-oauth2}). Must not be null.
+ * @param refreshToken a valid Auth0 refresh token to exchange. Must not be null.
+ * @param loginHint the user's ID within the identity provider specified by the connection
+ * (for example, the Google user ID when the connection is {@code google-oauth2}).
+ * May be null, in which case no {@code login_hint} is sent.
+ * @return a Request to configure and execute.
+ */
+ public TokenRequest getTokenForConnection(String connection, String refreshToken, String loginHint) {
+ Asserts.assertNotNull(connection, "connection");
+ Asserts.assertNotNull(refreshToken, "refresh token");
+
+ TokenRequest request = new TokenRequest(client, getTokenUrl());
+ request.addParameter(KEY_CLIENT_ID, clientId);
+ request.addParameter(
+ KEY_GRANT_TYPE, "urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token");
+ request.addParameter(KEY_SUBJECT_TOKEN, refreshToken);
+ request.addParameter(KEY_SUBJECT_TOKEN_TYPE, "urn:ietf:params:oauth:token-type:refresh_token");
+ request.addParameter(
+ KEY_REQUESTED_TOKEN_TYPE, "http://auth0.com/oauth/token-type/federated-connection-access-token");
+ request.addParameter(KEY_CONNECTION, connection);
+ if (loginHint != null) {
+ request.addParameter(KEY_LOGIN_HINT, loginHint);
+ }
+ addClientAuthentication(request, true);
+ return request;
+ }
+
/**
* Creates a request to revoke an existing Refresh Token.
* Confidential clients (Regular Web Apps) must have a client secret configured on this {@code AuthAPI} instance.
diff --git a/src/test/java/com/auth0/client/auth/AuthAPITest.java b/src/test/java/com/auth0/client/auth/AuthAPITest.java
index 8516480c..7278a80e 100644
--- a/src/test/java/com/auth0/client/auth/AuthAPITest.java
+++ b/src/test/java/com/auth0/client/auth/AuthAPITest.java
@@ -1035,6 +1035,82 @@ public void shouldCreateTokenExchangeRequestWithClientAssertion() throws Excepti
assertThat(response.getAccessToken(), not(emptyOrNullString()));
}
+ // Token Vault - Federated Connection Access Token
+
+ @Test
+ public void shouldThrowOnGetTokenForConnectionWithNullConnection() {
+ verifyThrows(
+ IllegalArgumentException.class,
+ () -> api.getTokenForConnection(null, "test-refresh-token", null),
+ "'connection' cannot be null!");
+ }
+
+ @Test
+ public void shouldThrowOnGetTokenForConnectionWithNullRefreshToken() {
+ verifyThrows(
+ IllegalArgumentException.class,
+ () -> api.getTokenForConnection("google-oauth2", null, null),
+ "'refresh token' cannot be null!");
+ }
+
+ @Test
+ public void shouldCreateGetTokenForConnectionRequest() throws Exception {
+ TokenRequest request = api.getTokenForConnection("google-oauth2", "test-refresh-token", null);
+ assertThat(request, is(notNullValue()));
+
+ server.jsonResponse(AUTH_TOKENS, 200);
+ TokenHolder response = request.execute().getBody();
+ RecordedRequest recordedRequest = server.takeRequest();
+
+ assertThat(recordedRequest, hasMethodAndPath(HttpMethod.POST, "/oauth/token"));
+ assertThat(recordedRequest, hasHeader("Content-Type", "application/json"));
+
+ Map