Skip to content

Commit 73b3a83

Browse files
committed
Initial commit
1 parent 296194f commit 73b3a83

File tree

4 files changed

+203
-1
lines changed

4 files changed

+203
-1
lines changed

README.md

+47-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,47 @@
1-
# oidc-claims
1+
# oidc-claims
2+
3+
Authenticates using OIDC and displays the claims from the ID token.
4+
5+
## Usage
6+
7+
Example usage:
8+
9+
```shell
10+
oidc-claims \
11+
-auth-url https://gitlab.com/oauth/authorize \
12+
-token-url https://gitlab.com/oauth/token \
13+
-client-id CLIENT_ID \
14+
-client-secret CLIENT_SECRET \
15+
-scopes openid,profile,email \
16+
-local-server-port 8000
17+
{
18+
"iss": "https://gitlab.com",
19+
"sub": "11",
20+
"aud": "[REDACTED]",
21+
"exp": 1732271262,
22+
"iat": 1732271142,
23+
"auth_time": 1732270319,
24+
"sub_legacy": "[REDACTED]",
25+
"name": "my_user",
26+
"nickname": "my_user",
27+
"preferred_username": "my_user",
28+
"email": "me@somewhere.io",
29+
"email_verified": true,
30+
"profile": "https://gitlab.com/my_user",
31+
"picture": "[REDACTED]",
32+
"groups_direct": [
33+
"group1",
34+
"group2"
35+
]
36+
}
37+
```
38+
39+
By default, the underlying library uses a dynamic server port. By specifying `-local-server-port`, you can specify a fixed port which can be used in the redirect URI.
40+
41+
Add `-debug` to display messages from the underlying libraries.
42+
43+
## Installation
44+
45+
```shell
46+
go install github.com/nicholasdille/oidc-claims
47+
```

go.mod

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module github.com/nicholasdille/oidc-claims
2+
3+
go 1.23.3
4+
5+
require (
6+
github.com/int128/kubelogin v1.31.0
7+
github.com/int128/oauth2cli v1.14.1
8+
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
9+
golang.org/x/oauth2 v0.24.0
10+
golang.org/x/sync v0.9.0
11+
)
12+
13+
require (
14+
cloud.google.com/go/compute/metadata v0.5.2 // indirect
15+
github.com/int128/listener v1.2.0 // indirect
16+
golang.org/x/sys v0.27.0 // indirect
17+
)

go.sum

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
2+
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
3+
cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
4+
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
5+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
7+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
8+
github.com/int128/kubelogin v1.31.0 h1:llwKwmuVYSjiKmMCDqXnYkx2x3mnAsYyCgXHIummWJA=
9+
github.com/int128/kubelogin v1.31.0/go.mod h1:t2a1H/DrQ7itXsjG3WR1fQxNjAGCYeyhqI75/7B5578=
10+
github.com/int128/listener v1.1.0 h1:2Jb41DWLpkQ3I9bIdBzO8H/tNwMvyl/OBZWtCV5Pjuw=
11+
github.com/int128/listener v1.1.0/go.mod h1:68WkmTN8PQtLzc9DucIaagAKeGVyMnyyKIkW4Xn47UA=
12+
github.com/int128/listener v1.2.0 h1:Gj+wLX1mCfetZWJz0wi7343JuP8qGrYcbavNQR2xye4=
13+
github.com/int128/listener v1.2.0/go.mod h1:k2nhHj+0PLFQ9VD15FnRubK8iJ5t9cif15HwhQ8Liok=
14+
github.com/int128/oauth2cli v1.14.1 h1:MxkiSSMT1RcsVKxyzaJYGgmMXvGWPXTMduhG4a1OqTs=
15+
github.com/int128/oauth2cli v1.14.1/go.mod h1:ha/eC3cUAixVzJ0V+voMRNQejLWGvk49AWDWN4Gawsk=
16+
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
17+
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
18+
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
19+
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
20+
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
21+
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
22+
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
23+
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
24+
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
25+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
26+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

main.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"log"
8+
"os"
9+
"strings"
10+
11+
"github.com/int128/oauth2cli"
12+
"github.com/int128/oauth2cli/oauth2params"
13+
"github.com/pkg/browser"
14+
"golang.org/x/oauth2"
15+
"golang.org/x/oauth2/google"
16+
"golang.org/x/sync/errgroup"
17+
18+
"github.com/int128/kubelogin/pkg/jwt"
19+
)
20+
21+
func init() {
22+
log.SetFlags(log.Lshortfile | log.Lmicroseconds)
23+
}
24+
25+
type cmdOptions struct {
26+
authURL string
27+
tokenURL string
28+
clientID string
29+
clientSecret string
30+
scopes string
31+
localServerPort string
32+
debug bool
33+
}
34+
35+
func main() {
36+
var o cmdOptions
37+
flag.StringVar(&o.authURL, "auth-url", google.Endpoint.AuthURL, "Authorization URL of the endpoint")
38+
flag.StringVar(&o.tokenURL, "token-url", google.Endpoint.TokenURL, "Authorization URL of the endpoint")
39+
flag.StringVar(&o.clientID, "client-id", "", "OAuth Client ID")
40+
flag.StringVar(&o.clientSecret, "client-secret", "", "OAuth Client Secret (optional)")
41+
flag.StringVar(&o.scopes, "scopes", "email", "Scopes to request, comma separated")
42+
flag.StringVar(&o.localServerPort, "local-server-port", "0", "Port number of the local server (optional)")
43+
flag.BoolVar(&o.debug, "debug", false, "Enable debug logging")
44+
flag.Parse()
45+
46+
log.SetOutput(os.Stderr)
47+
48+
if o.clientID == "" {
49+
log.Printf(`You need to set oauth2 credentials.
50+
Open https://console.cloud.google.com/apis/credentials and create a client.
51+
Then set the following options:`)
52+
flag.PrintDefaults()
53+
os.Exit(1)
54+
return
55+
}
56+
57+
pkce, err := oauth2params.NewPKCE()
58+
if err != nil {
59+
log.Fatalf("error: %s", err)
60+
}
61+
ready := make(chan string, 1)
62+
defer close(ready)
63+
cfg := oauth2cli.Config{
64+
OAuth2Config: oauth2.Config{
65+
ClientID: o.clientID,
66+
ClientSecret: o.clientSecret,
67+
Endpoint: oauth2.Endpoint{
68+
AuthURL: o.authURL,
69+
TokenURL: o.tokenURL,
70+
},
71+
Scopes: strings.Split(o.scopes, ","),
72+
},
73+
AuthCodeOptions: pkce.AuthCodeOptions(),
74+
TokenRequestOptions: pkce.TokenRequestOptions(),
75+
LocalServerReadyChan: ready,
76+
LocalServerBindAddress: []string{
77+
fmt.Sprintf("127.0.0.1:%s", o.localServerPort),
78+
"127.0.0.1:0",
79+
},
80+
}
81+
if o.debug {
82+
cfg.Logf = log.Printf
83+
}
84+
85+
ctx := context.Background()
86+
eg, ctx := errgroup.WithContext(ctx)
87+
eg.Go(func() error {
88+
select {
89+
case url := <-ready:
90+
if err := browser.OpenURL(url); err != nil {
91+
log.Printf("could not open the browser: %s", err)
92+
}
93+
return nil
94+
case <-ctx.Done():
95+
return fmt.Errorf("context done while waiting for authorization: %w", ctx.Err())
96+
}
97+
})
98+
eg.Go(func() error {
99+
token, err := oauth2cli.GetToken(ctx, cfg)
100+
if err != nil {
101+
return fmt.Errorf("could not get a token: %w", err)
102+
}
103+
claims, err := jwt.DecodeWithoutVerify(token.Extra("id_token").(string))
104+
if err != nil {
105+
return fmt.Errorf("could not decode the token: %w", err)
106+
}
107+
fmt.Printf("%s\n", claims.Pretty)
108+
return nil
109+
})
110+
if err := eg.Wait(); err != nil {
111+
log.Fatalf("authorization error: %s", err)
112+
}
113+
}

0 commit comments

Comments
 (0)