Skip to content

Commit 937167c

Browse files
authored
Support scope for self-signed JWT (#122)
1 parent f8ab771 commit 937167c

File tree

18 files changed

+130
-230
lines changed

18 files changed

+130
-230
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,19 @@ $ oauth2l fetch --type oauth --credentials ~/client_credentials.json --scope clo
261261
#### jwt
262262

263263
When jwt is selected and the json file specified in the `--credentials` option
264-
is a service account key file, a JWT token signed by the service account
265-
private key will be generated. When using this option, no scope parameter is
266-
needed but a single JWT audience must be provided. See how to construct the
267-
audience [here](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth).
268-
269-
```bash
270-
$ oauth2l fetch --type jwt --credentials ~/service_account.json --audience https://pubsub.googleapis.com/
271-
```
264+
is a service account key file, a JWT token signed by the service account private
265+
key will be generated. Either `--scope` or `--audience` must be specified for
266+
this option. See how to construct the audience [here](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth).
267+
268+
- With scope:
269+
```bash
270+
$ oauth2l fetch --type jwt --credentials ~/client_credentials.json --scope cloud-platform
271+
```
272+
273+
- With audience:
274+
```bash
275+
$ oauth2l fetch --type jwt --credentials ~/service_account.json --audience https://pubsub.googleapis.com/
276+
```
272277

273278
#### sso
274279

go.mod

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ module github.com/google/oauth2l
33
go 1.13
44

55
require (
6-
cloud.google.com/go v0.65.0 // indirect
7-
github.com/golang/protobuf v1.4.2 // indirect
86
github.com/jessevdk/go-flags v1.4.0
9-
github.com/wora/protorpc v0.0.0-20180730014223-ae9256a051d8 // indirect
10-
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
11-
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c
12-
google.golang.org/appengine v1.6.6 // indirect
13-
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect
14-
google.golang.org/grpc v1.31.0 // indirect
7+
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
158
)

go.sum

Lines changed: 4 additions & 168 deletions
Large diffs are not rendered by default.

integration/cli_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func TestCLI(t *testing.T) {
162162
{
163163
"fetch; jwt; no audience",
164164
[]string{"fetch", "--type", "jwt"},
165-
"no-audience.golden",
165+
"no-scope-or-audience.golden",
166166
false,
167167
},
168168
{

integration/golden/no-audience.golden

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
neither audience nor scope is provided

main.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func main() {
301301

302302
// Configure GUAC settings based on authType.
303303
var settings *util.Settings
304-
if authType == "jwt" {
304+
if authType == util.AuthTypeJWT {
305305
json, err := readJSON(credentials)
306306
if err != nil {
307307
fmt.Println("Failed to open file: " + credentials)
@@ -313,19 +313,16 @@ func main() {
313313
if audience == "" {
314314
if len(remainingArgs) > 0 {
315315
audience = remainingArgs[0]
316-
} else {
317-
fmt.Println("Missing audience argument for JWT")
318-
return
319316
}
320317
}
321318

322-
// JWT flow requires empty Scope.
323-
// Also, JWT currently does not work with STS.
324319
settings = &util.Settings{
320+
AuthType: util.AuthTypeJWT,
325321
CredentialsJSON: json,
326322
Audience: audience,
323+
Scope: scope,
327324
}
328-
} else if authType == "sso" {
325+
} else if authType == util.AuthTypeSSO {
329326
// Fallback to reading email from first remaining arg
330327
argProcessedIndex := 0
331328
if email == "" {
@@ -380,6 +377,7 @@ func main() {
380377
Sts: sts,
381378
ServiceAccount: serviceAccount,
382379
Email: email,
380+
AuthType: util.AuthTypeOAuth,
383381
}
384382
}
385383

util/fetch.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ package util
1616

1717
import (
1818
"context"
19+
"errors"
20+
"fmt"
1921
"strings"
2022

2123
"golang.org/x/oauth2"
@@ -31,12 +33,15 @@ func newTokenSource(ctx context.Context, settings *Settings) (*oauth2.TokenSourc
3133
var err error
3234
if settings == nil {
3335
ts, err = google.DefaultTokenSource(ctx, DefaultScope)
34-
} else if settings.APIKey != "" {
36+
} else if settings.GetAuthType() == AuthTypeAPIKey {
3537
return nil, nil
36-
} else if settings.Scope != "" {
38+
} else if settings.GetAuthType() == AuthTypeOAuth {
3739
ts, err = OAuthJSONTokenSource(ctx, settings)
38-
} else {
40+
} else if settings.GetAuthType() == AuthTypeJWT {
3941
ts, err = JWTTokenSource(ctx, settings)
42+
} else {
43+
return nil, fmt.Errorf(
44+
"Unsupported authentcation method: %s", settings.GetAuthType())
4045
}
4146
if err != nil {
4247
return nil, err
@@ -76,8 +81,13 @@ func JWTTokenSource(ctx context.Context, settings *Settings) (oauth2.TokenSource
7681
if err != nil {
7782
return nil, err
7883
}
79-
ts, err := google.JWTAccessTokenSourceFromJSON(creds.JSON, settings.Audience)
80-
return ts, err
84+
if settings.Audience != "" {
85+
return google.JWTAccessTokenSourceFromJSON(creds.JSON, settings.Audience)
86+
} else if settings.Scope != "" {
87+
return google.JWTAccessTokenSourceWithScope(creds.JSON, settings.Scope)
88+
} else {
89+
return nil, errors.New("neither audience nor scope is provided")
90+
}
8191
}
8292

8393
// FindJSONCredentials obtains credentials from settings or Application Default Credentials

util/settings.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ import (
1818
"golang.org/x/oauth2/authhandler"
1919
)
2020

21-
var MethodOAuth = "oauth"
22-
var MethodJWT = "jwt"
23-
var MethodAPIKey = "apikey"
21+
var AuthTypeOAuth = "oauth"
22+
var AuthTypeJWT = "jwt"
23+
var AuthTypeAPIKey = "apikey"
24+
var AuthTypeSSO = "sso"
2425

2526
// An extensible structure that holds the credentials for
2627
// Google API authentication.
2728
type Settings struct {
2829
// The JSON credentials content downloaded from Google Cloud Console.
2930
CredentialsJSON string
31+
// The authentication type.
32+
AuthType string
3033
// If specified, use OAuth. Otherwise, JWT.
3134
Scope string
3235
// The audience field for JWT auth
@@ -52,11 +55,13 @@ type Settings struct {
5255
ServiceAccount string
5356
}
5457

55-
func (s Settings) AuthMethod() string {
56-
if s.APIKey != "" {
57-
return MethodAPIKey
58+
func (s Settings) GetAuthType() string {
59+
if s.AuthType != "" {
60+
return s.AuthType
61+
} else if s.APIKey != "" {
62+
return AuthTypeAPIKey
5863
} else if s.Scope != "" {
59-
return MethodOAuth
64+
return AuthTypeOAuth
6065
}
61-
return MethodJWT
66+
return AuthTypeJWT
6267
}

vendor/github.com/jessevdk/go-flags/completion.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)