Skip to content

Commit 37fc6dd

Browse files
committed
feat: Add Custom Token Exchange Support
1 parent e7dd331 commit 37fc6dd

34 files changed

Lines changed: 3980 additions & 7 deletions

.fernignore

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,12 @@ src/main/java/com/auth0/client/LoggingOptions.java
3232
# TokenProvider interface (shared between Fern-generated Management API and auth0-provided Authentication API)
3333
src/main/java/com/auth0/client/mgmt/TokenProvider.java
3434

35-
# Test infrastructure from auth0-real
36-
src/test/java/com/auth0/net/
37-
src/test/java/com/auth0/exception/
38-
src/test/java/com/auth0/utils/
39-
src/test/java/com/auth0/json/
35+
# Shared test infrastructure for the Authentication API tests (manually maintained from auth0-real)
36+
src/test/java/com/auth0/client/MockServer.java
37+
src/test/java/com/auth0/client/RecordedRequestMatcher.java
38+
src/test/java/com/auth0/client/UrlMatcher.java
39+
src/test/java/com/auth0/AssertsUtil.java
4040
src/test/resources/auth/
41-
src/test/resources/keys/
42-
src/test/resources/mgmt/
4341
src/test/resources/mockito-extensions/
4442
src/test/java/com/auth0/client/legacy/
4543

src/main/java/com/auth0/client/auth/AuthAPI.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class AuthAPI {
5757
private static final String KEY_MFA_TOKEN = "mfa_token";
5858
private static final String KEY_CLIENT_ASSERTION = "client_assertion";
5959
private static final String KEY_CLIENT_ASSERTION_TYPE = "client_assertion_type";
60+
private static final String KEY_SUBJECT_TOKEN = "subject_token";
61+
private static final String KEY_SUBJECT_TOKEN_TYPE = "subject_token_type";
6062
private static final String PATH_OAUTH = "oauth";
6163
private static final String PATH_TOKEN = "token";
6264
private static final String PATH_DBCONNECTIONS = "dbconnections";
@@ -800,6 +802,44 @@ public TokenRequest requestToken(String audience, String org) {
800802
return request;
801803
}
802804

805+
/**
806+
* Creates a request to exchange an external subject token for Auth0 tokens using the
807+
* {@code urn:ietf:params:oauth:grant-type:token-exchange} grant (Custom Token Exchange).
808+
* A Token Exchange Profile that maps the given {@code subjectTokenType} must be configured on the tenant, and
809+
* client authentication (client secret or client assertion) is required.
810+
* <pre>
811+
* {@code
812+
* try {
813+
* TokenHolder result = authAPI.exchangeToken("test-user123-john@example.com", "urn:mycompany:m2m-test-token")
814+
* .setAudience("https://myapi.me.auth0.com/users")
815+
* .setScope("openid profile email")
816+
* .execute()
817+
* .getBody();
818+
* } catch (Auth0Exception e) {
819+
* //Something happened
820+
* }
821+
* }
822+
* </pre>
823+
*
824+
* @see <a href="https://auth0.com/docs/authenticate/custom-token-exchange">Custom Token Exchange documentation</a>
825+
* @param subjectToken the external token representing the identity of the subject. Must not be null.
826+
* @param subjectTokenType an identifier for the type of the {@code subjectToken}, matching a configured Token
827+
* Exchange Profile (for example {@code urn:mycompany:m2m-test-token}). Must not be null.
828+
* @return a Request to configure and execute.
829+
*/
830+
public TokenRequest exchangeToken(String subjectToken, String subjectTokenType) {
831+
Asserts.assertNotNull(subjectToken, "subject token");
832+
Asserts.assertNotNull(subjectTokenType, "subject token type");
833+
834+
TokenRequest request = new TokenRequest(client, getTokenUrl());
835+
request.addParameter(KEY_CLIENT_ID, clientId);
836+
request.addParameter(KEY_GRANT_TYPE, "urn:ietf:params:oauth:grant-type:token-exchange");
837+
request.addParameter(KEY_SUBJECT_TOKEN, subjectToken);
838+
request.addParameter(KEY_SUBJECT_TOKEN_TYPE, subjectTokenType);
839+
addClientAuthentication(request, true);
840+
return request;
841+
}
842+
803843
/**
804844
* Creates a request to revoke an existing Refresh Token.
805845
* Confidential clients (Regular Web Apps) <strong>must</strong> have a client secret configured on this {@code AuthAPI} instance.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.auth0;
2+
3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.is;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import org.junit.jupiter.api.function.Executable;
8+
9+
public class AssertsUtil {
10+
11+
public static <T extends Throwable> T verifyThrows(Class<T> expectedType, Executable executable) {
12+
return assertThrows(expectedType, executable);
13+
}
14+
15+
public static <T extends Throwable> T verifyThrows(Class<T> expectedType, Executable executable, String message) {
16+
T result = assertThrows(expectedType, executable);
17+
assertThat(result.getMessage(), is(message));
18+
return result;
19+
}
20+
}

0 commit comments

Comments
 (0)