Skip to content

Commit 1e551fc

Browse files
authored
Merge branch 'master' into dependabot/github_actions/actions/setup-java-5.6.0
2 parents ec48819 + e6870e7 commit 1e551fc

67 files changed

Lines changed: 4090 additions & 59 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.fern/replay.lock

Lines changed: 393 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

EXAMPLES.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Management API usage](#management-api-usage)
66
- [Verifying an ID token](#verifying-an-id-token)
77
- [Organizations](#organizations)
8+
- [Token Vault](#token-vault)
89
- [Logging](#logging)
910
- [Asynchronous operations](#asynchronous-operations)
1011

@@ -325,6 +326,57 @@ String url = auth.authorizeUrl("https://me.auth0.com/callback")
325326
.build();
326327
```
327328

329+
## Token Vault
330+
331+
[Token Vault](https://auth0.com/docs/secure/tokens/token-vault) lets you exchange an Auth0 token for a federated identity provider's access token, so your application can call the provider's APIs on the user's behalf. The connection must have Token Vault enabled, and because this exchange requires a private client, the `AuthAPI` instance must be configured with a client secret or client assertion.
332+
333+
### Exchange a refresh token
334+
335+
Use `getTokenForConnectionWithRefreshToken()` to exchange an Auth0 refresh token for the federated provider's access token:
336+
337+
```java
338+
AuthAPI auth = AuthAPI.newBuilder("{YOUR_DOMAIN}", "{YOUR_CLIENT_ID}", "{YOUR_CLIENT_SECRET}").build();
339+
TokenHolder result = auth.getTokenForConnectionWithRefreshToken("google-oauth2", "{REFRESH_TOKEN}", null)
340+
.execute()
341+
.getBody();
342+
String federatedAccessToken = result.getAccessToken();
343+
```
344+
345+
### Exchange an access token
346+
347+
Use `getTokenForConnectionWithAccessToken()` to exchange an Auth0 access token instead:
348+
349+
```java
350+
TokenHolder result = auth.getTokenForConnectionWithAccessToken("google-oauth2", "{ACCESS_TOKEN}", null)
351+
.execute()
352+
.getBody();
353+
String federatedAccessToken = result.getAccessToken();
354+
```
355+
356+
### Specifying a login hint
357+
358+
When a user has multiple accounts on the same connection, pass their ID within the identity provider as the `loginHint` (the final argument). Pass `null` to omit it:
359+
360+
```java
361+
TokenHolder result = auth.getTokenForConnectionWithRefreshToken("google-oauth2", "{REFRESH_TOKEN}", "{GOOGLE_USER_ID}")
362+
.execute()
363+
.getBody();
364+
```
365+
366+
### Exchanging other token types
367+
368+
For full control over the subject token type, use the generic `getTokenForConnection()` and supply the `subject_token_type` URN yourself:
369+
370+
```java
371+
TokenHolder result = auth.getTokenForConnection(
372+
"google-oauth2",
373+
"{SUBJECT_TOKEN}",
374+
"urn:ietf:params:oauth:token-type:refresh_token",
375+
"{GOOGLE_USER_ID}")
376+
.execute()
377+
.getBody();
378+
```
379+
328380
## Logging
329381
330382
The SDK is silent by default. You can enable logging to see HTTP requests and responses, which is useful for debugging.

reference.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ client.clients().list(
13021302
<dl>
13031303
<dd>
13041304

1305-
**externalClientId:** `Optional<String>` — Optional filter by the <a href="https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-04.html">Client ID Metadata Document</a> URI for CIMD-registered clients.
1305+
**externalClientId:** `Optional<String>` — Optional filter by the <a href="https://drafts.oauth.net/draft-ietf-oauth-client-id-metadata-document/draft-ietf-oauth-client-id-metadata-document.html">Client ID Metadata Document</a> URI for CIMD-registered clients.
13061306

13071307
</dd>
13081308
</dl>
@@ -1786,6 +1786,14 @@ See https://auth0.com/docs/secure/security-guidance/measures-against-app-imperso
17861786
<dl>
17871787
<dd>
17881788

1789+
**identityAssertionAuthorizationGrant:** `Optional<CreateIdentityAssertionAuthorizationGrant>`
1790+
1791+
</dd>
1792+
</dl>
1793+
1794+
<dl>
1795+
<dd>
1796+
17891797
**thirdPartySecurityMode:** `Optional<ClientThirdPartySecurityModeEnum>`
17901798

17911799
</dd>
@@ -2411,6 +2419,14 @@ client.clients().update(
24112419
<dl>
24122420
<dd>
24132421

2422+
**identityAssertionAuthorizationGrant:** `Optional<UpdateIdentityAssertionAuthorizationGrant>`
2423+
2424+
</dd>
2425+
</dl>
2426+
2427+
<dl>
2428+
<dd>
2429+
24142430
**formTemplate:** `Optional<String>` — Form template for WS-Federation protocol
24152431

24162432
</dd>
@@ -3424,6 +3440,14 @@ client.connections().create(
34243440

34253441
**crossAppAccessRequestingApp:** `Optional<CrossAppAccessRequestingApp>`
34263442

3443+
</dd>
3444+
</dl>
3445+
3446+
<dl>
3447+
<dd>
3448+
3449+
**crossAppAccessResourceApp:** `Optional<CreateCrossAppAccessResourceApp>`
3450+
34273451
</dd>
34283452
</dl>
34293453
</dd>
@@ -3698,6 +3722,14 @@ client.connections().update(
36983722

36993723
**crossAppAccessRequestingApp:** `Optional<CrossAppAccessRequestingApp>`
37003724

3725+
</dd>
3726+
</dl>
3727+
3728+
<dl>
3729+
<dd>
3730+
3731+
**crossAppAccessResourceApp:** `Optional<UpdateCrossAppAccessResourceApp>`
3732+
37013733
</dd>
37023734
</dl>
37033735
</dd>
@@ -16871,6 +16903,14 @@ client.branding().themes().create(
1687116903
<dl>
1687216904
<dd>
1687316905

16906+
**identifiers:** `Optional<BrandingThemeIdentifiers>`
16907+
16908+
</dd>
16909+
</dl>
16910+
16911+
<dl>
16912+
<dd>
16913+
1687416914
**pageBackground:** `BrandingThemePageBackground`
1687516915

1687616916
</dd>
@@ -17228,6 +17268,14 @@ client.branding().themes().update(
1722817268
<dl>
1722917269
<dd>
1723017270

17271+
**identifiers:** `Optional<BrandingThemeIdentifiers>`
17272+
17273+
</dd>
17274+
</dl>
17275+
17276+
<dl>
17277+
<dd>
17278+
1723117279
**pageBackground:** `BrandingThemePageBackground`
1723217280

1723317281
</dd>
@@ -29546,6 +29594,14 @@ client.selfServiceProfiles().ssoTicket().create(
2954629594
<dl>
2954729595
<dd>
2954829596

29597+
**thirdPartyClientAccessConfig:** `Optional<ThirdPartyClientAccessConfig>`
29598+
29599+
</dd>
29600+
</dl>
29601+
29602+
<dl>
29603+
<dd>
29604+
2954929605
**enabledFeatures:** `Optional<SelfServiceProfileSsoTicketEnabledFeatures>`
2955029606

2955129607
</dd>

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

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -843,15 +843,20 @@ public TokenRequest exchangeToken(String subjectToken, String subjectTokenType)
843843
}
844844

845845
/**
846-
* Creates a request to exchange an Auth0 refresh token for a federated identity provider's access token
846+
* Creates a request to exchange a subject token for a federated identity provider's access token
847847
* using the Token Vault grant
848848
* {@code urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token}.
849+
* This is the generic entry point: the caller supplies both the {@code subjectToken} and its
850+
* {@code subjectTokenType}, so no assumption is made about which kind of token is being exchanged.
851+
* For the common cases, prefer {@link #getTokenForConnectionWithRefreshToken(String, String, String)}
852+
* or {@link #getTokenForConnectionWithAccessToken(String, String, String)}.
849853
* The connection must have the token vault enabled, and client authentication
850854
* (client secret or client assertion) is required as this must be a private client.
851855
* <pre>
852856
* {@code
853857
* try {
854-
* TokenHolder result = authAPI.getTokenForConnection("google-oauth2", refreshToken, "google-user-id")
858+
* TokenHolder result = authAPI.getTokenForConnection(
859+
* "google-oauth2", subjectToken, "urn:ietf:params:oauth:token-type:refresh_token", "google-user-id")
855860
* .execute()
856861
* .getBody();
857862
* String federatedAccessToken = result.getAccessToken();
@@ -864,22 +869,27 @@ public TokenRequest exchangeToken(String subjectToken, String subjectTokenType)
864869
* @see <a href="https://auth0.com/docs/secure/tokens/token-vault">Token Vault documentation</a>
865870
* @param connection the name of the federated connection to obtain an access token for
866871
* (for example {@code google-oauth2}). Must not be null.
867-
* @param refreshToken a valid Auth0 refresh token to exchange. Must not be null.
872+
* @param subjectToken the Auth0 token to exchange. Must not be null.
873+
* @param subjectTokenType the identifier for the type of {@code subjectToken}, for example
874+
* {@code urn:ietf:params:oauth:token-type:refresh_token} or
875+
* {@code urn:ietf:params:oauth:token-type:access_token}. Must not be null.
868876
* @param loginHint the user's ID within the identity provider specified by the connection
869877
* (for example, the Google user ID when the connection is {@code google-oauth2}).
870878
* May be null, in which case no {@code login_hint} is sent.
871879
* @return a Request to configure and execute.
872880
*/
873-
public TokenRequest getTokenForConnection(String connection, String refreshToken, String loginHint) {
881+
public TokenRequest getTokenForConnection(
882+
String connection, String subjectToken, String subjectTokenType, String loginHint) {
874883
Asserts.assertNotNull(connection, "connection");
875-
Asserts.assertNotNull(refreshToken, "refresh token");
884+
Asserts.assertNotNull(subjectToken, "subject token");
885+
Asserts.assertNotNull(subjectTokenType, "subject token type");
876886

877887
TokenRequest request = new TokenRequest(client, getTokenUrl());
878888
request.addParameter(KEY_CLIENT_ID, clientId);
879889
request.addParameter(
880890
KEY_GRANT_TYPE, "urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token");
881-
request.addParameter(KEY_SUBJECT_TOKEN, refreshToken);
882-
request.addParameter(KEY_SUBJECT_TOKEN_TYPE, "urn:ietf:params:oauth:token-type:refresh_token");
891+
request.addParameter(KEY_SUBJECT_TOKEN, subjectToken);
892+
request.addParameter(KEY_SUBJECT_TOKEN_TYPE, subjectTokenType);
883893
request.addParameter(
884894
KEY_REQUESTED_TOKEN_TYPE, "http://auth0.com/oauth/token-type/federated-connection-access-token");
885895
request.addParameter(KEY_CONNECTION, connection);
@@ -890,6 +900,97 @@ public TokenRequest getTokenForConnection(String connection, String refreshToken
890900
return request;
891901
}
892902

903+
/**
904+
* Convenience method to exchange an Auth0 refresh token for a federated identity provider's access token
905+
* using the Token Vault grant. Delegates to
906+
* {@link #getTokenForConnection(String, String, String, String)} with the subject token type
907+
* {@code urn:ietf:params:oauth:token-type:refresh_token}.
908+
* The connection must have the token vault enabled, and client authentication
909+
* (client secret or client assertion) is required as this must be a private client.
910+
* <pre>
911+
* {@code
912+
* try {
913+
* TokenHolder result = authAPI.getTokenForConnectionWithRefreshToken("google-oauth2", refreshToken, "google-user-id")
914+
* .execute()
915+
* .getBody();
916+
* String federatedAccessToken = result.getAccessToken();
917+
* } catch (Auth0Exception e) {
918+
* //Something happened
919+
* }
920+
* }
921+
* </pre>
922+
*
923+
* @see <a href="https://auth0.com/docs/secure/tokens/token-vault">Token Vault documentation</a>
924+
* @param connection the name of the federated connection to obtain an access token for
925+
* (for example {@code google-oauth2}). Must not be null.
926+
* @param refreshToken a valid Auth0 refresh token to exchange. Must not be null.
927+
* @param loginHint the user's ID within the identity provider specified by the connection
928+
* (for example, the Google user ID when the connection is {@code google-oauth2}).
929+
* May be null, in which case no {@code login_hint} is sent.
930+
* @return a Request to configure and execute.
931+
*/
932+
public TokenRequest getTokenForConnectionWithRefreshToken(
933+
String connection, String refreshToken, String loginHint) {
934+
Asserts.assertNotNull(refreshToken, "refresh token");
935+
return getTokenForConnection(
936+
connection, refreshToken, "urn:ietf:params:oauth:token-type:refresh_token", loginHint);
937+
}
938+
939+
/**
940+
* Convenience method to exchange an Auth0 access token for a federated identity provider's access token
941+
* using the Token Vault grant. Delegates to
942+
* {@link #getTokenForConnection(String, String, String, String)} with the subject token type
943+
* {@code urn:ietf:params:oauth:token-type:access_token}.
944+
* The connection must have the token vault enabled, and client authentication
945+
* (client secret or client assertion) is required as this must be a private client.
946+
* <pre>
947+
* {@code
948+
* try {
949+
* TokenHolder result = authAPI.getTokenForConnectionWithAccessToken("google-oauth2", accessToken, "google-user-id")
950+
* .execute()
951+
* .getBody();
952+
* String federatedAccessToken = result.getAccessToken();
953+
* } catch (Auth0Exception e) {
954+
* //Something happened
955+
* }
956+
* }
957+
* </pre>
958+
*
959+
* @see <a href="https://auth0.com/docs/secure/tokens/token-vault">Token Vault documentation</a>
960+
* @param connection the name of the federated connection to obtain an access token for
961+
* (for example {@code google-oauth2}). Must not be null.
962+
* @param accessToken a valid Auth0 access token to exchange. Must not be null.
963+
* @param loginHint the user's ID within the identity provider specified by the connection
964+
* (for example, the Google user ID when the connection is {@code google-oauth2}).
965+
* May be null, in which case no {@code login_hint} is sent.
966+
* @return a Request to configure and execute.
967+
*/
968+
public TokenRequest getTokenForConnectionWithAccessToken(String connection, String accessToken, String loginHint) {
969+
Asserts.assertNotNull(accessToken, "access token");
970+
return getTokenForConnection(
971+
connection, accessToken, "urn:ietf:params:oauth:token-type:access_token", loginHint);
972+
}
973+
974+
/**
975+
* Creates a request to exchange an Auth0 refresh token for a federated identity provider's access token
976+
* using the Token Vault grant.
977+
*
978+
* @deprecated Use {@link #getTokenForConnectionWithRefreshToken(String, String, String)} to exchange a
979+
* refresh token, or {@link #getTokenForConnectionWithAccessToken(String, String, String)} to
980+
* exchange an access token. For full control over the subject token type, use
981+
* {@link #getTokenForConnection(String, String, String, String)}.
982+
* @param connection the name of the federated connection to obtain an access token for
983+
* (for example {@code google-oauth2}). Must not be null.
984+
* @param refreshToken a valid Auth0 refresh token to exchange. Must not be null.
985+
* @param loginHint the user's ID within the identity provider specified by the connection.
986+
* May be null, in which case no {@code login_hint} is sent.
987+
* @return a Request to configure and execute.
988+
*/
989+
@Deprecated
990+
public TokenRequest getTokenForConnection(String connection, String refreshToken, String loginHint) {
991+
return getTokenForConnectionWithRefreshToken(connection, refreshToken, loginHint);
992+
}
993+
893994
/**
894995
* Creates a request to revoke an existing Refresh Token.
895996
* Confidential clients (Regular Web Apps) <strong>must</strong> have a client secret configured on this {@code AuthAPI} instance.

0 commit comments

Comments
 (0)