Skip to content

Commit 58e068c

Browse files
authored
Token exchange (#20)
1 parent c1164f1 commit 58e068c

File tree

12 files changed

+398
-145
lines changed

12 files changed

+398
-145
lines changed

README.md

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
## Features
1313

1414
* A simple and intuitive interface for quickly trying out different OAuth 2.0 grant types and client authentication methods
15-
* Supports all modern OAuth 2.0 grant types: authorization code, implicit, password, client credentials, refresh token, JWT bearer
15+
* Supports all modern OAuth 2.0 grant types: authorization code, implicit, password, client credentials, refresh token, JWT bearer, token exchange
1616
* Supports all client authentication methods: client secret basic, client secret post, client secret JWT, private key JWT, TLS client auth
1717

1818
## Installation
@@ -59,26 +59,30 @@ oauth2c [issuer url] [flags]
5959
The available flags are:
6060

6161
``` sh
62-
--assertion string claims for jwt bearer assertion
63-
--auth-method string token endpoint authentication method
64-
--client-id string client identifier
65-
--client-secret string client secret
66-
--grant-type string grant type
67-
-h, --help help for oauthc
68-
--insecure allow insecure connections
69-
--no-pkce disable proof key for code exchange (PKCE)
70-
--password string resource owner password credentials grant flow password
71-
--pkce enable proof key for code exchange (PKCE)
72-
--refresh-token string refresh token
73-
--response-mode string response mode
74-
--response-types strings response type
75-
--scopes strings requested scopes
76-
--signing-key string path or url to signing key in jwks format
77-
-s, --silent silent mode
78-
--tls-cert string path to tls cert pem file
79-
--tls-key string path to tls key pem file
80-
--tls-root-ca string path to tls root ca pem file
81-
--username string resource owner password credentials grant flow username
62+
--actor-token string acting party access token
63+
--actor-token-type string acting party access token type
64+
--assertion string claims for jwt bearer assertion
65+
--auth-method string token endpoint authentication method
66+
--client-id string client identifier
67+
--client-secret string client secret
68+
--grant-type string grant type
69+
-h, --help help for oauthc
70+
--insecure allow insecure connections
71+
--no-pkce disable proof key for code exchange (PKCE)
72+
--password string resource owner password credentials grant flow password
73+
--pkce enable proof key for code exchange (PKCE)
74+
--refresh-token string refresh token
75+
--response-mode string response mode
76+
--response-types strings response type
77+
--scopes strings requested scopes
78+
--signing-key string path or url to signing key in jwks format
79+
-s, --silent silent mode
80+
--subject-token string third party access token
81+
--subject-token-type string third party access token type
82+
--tls-cert string path to tls cert pem file
83+
--tls-key string path to tls key pem file
84+
--tls-root-ca string path to tls root ca pem file
85+
--username string resource owner password credentials grant flow username
8286
```
8387

8488
You will be asked to provide the necessary information, such as the grant type, client authentication method, and any other relevant details (if not already provided).
@@ -267,6 +271,52 @@ oauth2c https://oauth2c.us.authz.cloudentity.io/oauth2c/demo \
267271

268272
[Learn more about the jwt bearer flow](https://cloudentity.com/developers/basics/oauth-grant-types/using-jwt-profile-for-authorization-flows/)
269273

274+
#### Token exchange
275+
276+
The token exchange OAuth2 grant flow involves the client providing an access token to the OAuth2 server,
277+
which then returns a new access token. This grant type is typically used when the client and the OAuth2
278+
server have a pre-existing trust relationship, such as when the client is a trusted third-party.
279+
280+
``` sh
281+
oauth2c https://oauth2c.us.authz.cloudentity.io/oauth2c/demo \
282+
--client-id cauktionbud6q8ftlqq0 \
283+
--client-secret HCwQ5uuUWBRHd04ivjX5Kl0Rz8zxMOekeLtqzki0GPc \
284+
--grant-type urn:ietf:params:oauth:grant-type:token-exchange \
285+
--auth-method client_secret_basic \
286+
--scopes email \
287+
--subject-token $SUBJECT_TOKEN \
288+
--subject-token-type urn:ietf:params:oauth:token-type:access_token \
289+
--actor-token $ACTOR_TOKEN \
290+
--actor-token-type urn:ietf:params:oauth:token-type:access_token
291+
```
292+
293+
> **Note** In order to use this command, you must first set the SUBJECT_TOKEN and ACTOR_TOKEN environment variables
294+
>
295+
> ``` sh
296+
> export SUBJECT_TOKEN=`oauth2c https://oauth2c.us.authz.cloudentity.io/oauth2c/demo \
297+
> --client-id cauktionbud6q8ftlqq0 \
298+
> --client-secret HCwQ5uuUWBRHd04ivjX5Kl0Rz8zxMOekeLtqzki0GPc \
299+
> --response-types code \
300+
> --response-mode query \
301+
> --grant-type authorization_code \
302+
> --auth-method client_secret_basic \
303+
> --scopes openid,email,offline_access \
304+
> --no-pkce \
305+
> --silent | jq -r .access_token`
306+
> ```
307+
308+
> ``` sh
309+
> export ACTOR_TOKEN=`oauth2c https://oauth2c.us.authz.cloudentity.io/oauth2c/demo \
310+
> --client-id cauktionbud6q8ftlqq0 \
311+
> --client-secret HCwQ5uuUWBRHd04ivjX5Kl0Rz8zxMOekeLtqzki0GPc \
312+
> --grant-type client_credentials \
313+
> --auth-method client_secret_basic \
314+
> --scopes introspect_tokens,revoke_tokens \
315+
> --silent | jq -r .access_token`
316+
> ```
317+
318+
[Learn more about the token exchange flow](https://cloudentity.com/developers/basics/oauth-grant-types/token-exchange/)
319+
270320
### Auth methods
271321
272322
#### Client Secret Basic

cmd/log.go

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ func LogInputData(cc oauth2.ClientConfig) {
9898
{"Username", cc.Username},
9999
{"Password", cc.Password},
100100
{"Refresh token", cc.RefreshToken},
101+
{"Signing key", cc.SigningKey},
102+
{"Subject token type", cc.SubjectTokenType},
103+
{"Actors token type", cc.ActorTokenType},
104+
{"TLS client cert", cc.TLSCert},
105+
{"TLS client key", cc.TLSKey},
106+
{"TLS root CA", cc.TLSRootCA},
101107
}
102108

103109
nonEmptyData := pterm.TableData{}
@@ -278,7 +284,7 @@ func LogAssertion(request oauth2.Request, title string, name string) {
278284
}
279285

280286
pterm.DefaultBox.WithTitle(title).Printfln("%s = JWT-%s(payload)", name, token.Header["alg"])
281-
pterm.Println("")
287+
pterm.Println()
282288
pterm.Println("Payload")
283289
LogJson(claims)
284290
pterm.Println("")
@@ -317,20 +323,38 @@ func LogAssertion(request oauth2.Request, title string, name string) {
317323
pterm.FgGray.Println(string(key))
318324
}
319325

320-
pterm.Println("")
326+
pterm.Println()
321327
}
322328

323-
func LogResult(result interface{}) {
324-
if !silent {
329+
func LogSubjectTokenAndActorToken(request oauth2.Request) {
330+
var (
331+
subjectToken = request.Form.Get("subject_token")
332+
actorToken = request.Form.Get("actor_token")
333+
subjectTokenClaims jwt.MapClaims
334+
actorTokenClaims jwt.MapClaims
335+
)
336+
337+
if silent {
325338
return
326339
}
327340

328-
output, err := json.Marshal(result)
341+
if subjectToken != "" {
342+
if _, _, err := parser.ParseUnverified(subjectToken, &subjectTokenClaims); err != nil {
343+
pterm.Error.Println(err)
344+
} else {
345+
pterm.Println(pterm.FgGray.Sprint("Subject token:"))
346+
LogJson(subjectTokenClaims)
347+
}
348+
}
329349

330-
if err != nil {
331-
pterm.Error.Println(err)
332-
return
350+
if actorToken != "" {
351+
if _, _, err := parser.ParseUnverified(actorToken, &actorTokenClaims); err != nil {
352+
pterm.Error.Println(err)
353+
} else {
354+
pterm.Println(pterm.FgGray.Sprint("Actor token:"))
355+
LogJson(actorTokenClaims)
356+
}
333357
}
334358

335-
pterm.Println(string(output))
359+
pterm.Println()
336360
}

0 commit comments

Comments
 (0)