Last active
February 29, 2024 21:28
-
-
Save looselycoupled/b2074b3f3e8b6800cddc6893ce8ef74a to your computer and use it in GitHub Desktop.
Quick demonstration to create a JWKS, sign a token, and then validate it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/ed25519" | |
"crypto/rand" | |
"encoding/json" | |
"fmt" | |
"time" | |
"github.com/lestrrat-go/jwx/v2/jwa" | |
"github.com/lestrrat-go/jwx/v2/jwk" | |
"github.com/lestrrat-go/jwx/v2/jwt" | |
) | |
func make() (pubJWKSetBytes, tokenBytes []byte, err error) { | |
_, sk, err := ed25519.GenerateKey(rand.Reader) | |
if err != nil { | |
return nil, nil, err | |
} | |
key, err := jwk.FromRaw(sk) | |
if err != nil { | |
return nil, nil, err | |
} | |
if err = key.Set(jwk.KeyIDKey, "ci-test-key"); err != nil { | |
return nil, nil, err | |
} | |
pkey, err := jwk.PublicKeyOf(key) | |
if err != nil { | |
return nil, nil, err | |
} | |
if err = pkey.Set(jwk.KeyIDKey, "ci-test-key"); err != nil { | |
return nil, nil, err | |
} | |
if err = pkey.Set(jwk.AlgorithmKey, jwa.EdDSA); err != nil { | |
return nil, nil, err | |
} | |
pubJWKSet := jwk.NewSet() | |
if err = pubJWKSet.AddKey(pkey); err != nil { | |
return nil, nil, err | |
} | |
pubJWKSetBytes, err = json.Marshal(pubJWKSet) | |
if err != nil { | |
return nil, nil, err | |
} | |
token, err := jwt.NewBuilder(). | |
Issuer(`antimatter/ci`). | |
IssuedAt(time.Now()). | |
Subject(`test-user`). | |
Expiration(time.Now().Add(time.Hour * 24 * 3650)). | |
Build() | |
signedToken, err := jwt.Sign(token, jwt.WithKey(jwa.EdDSA, key)) | |
if err != nil { | |
return nil, nil, err | |
} | |
// Verify the token | |
_, err = jwt.Parse(signedToken, jwt.WithKeySet(pubJWKSet), jwt.WithValidate(true)) | |
if err != nil { | |
return nil, nil, err | |
} | |
return pubJWKSetBytes, signedToken, err | |
} | |
func validate(setBytes, tokenBytes []byte) error { | |
// Parse the JSON string to create a jwk.Set | |
set, err := jwk.Parse(setBytes) | |
if err != nil { | |
return fmt.Errorf("Error parsing JWKS: %w\n", err) | |
} | |
token, err := jwt.Parse(tokenBytes, jwt.WithKeySet(set), jwt.WithValidate(true)) | |
if err != nil { | |
return fmt.Errorf("Failed to parse or verify JWT: %w\n", err) | |
} | |
fmt.Printf("Token: %#v\n", token) | |
return nil | |
} | |
func main() { | |
s, t, err := make() | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("keyset: %s\n", s) | |
fmt.Printf("signed token: %s\n", t) | |
if err = validate(s, t); err != nil { | |
panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment