token.go raw
1 package internal
2
3 import (
4 "crypto/rsa"
5 "crypto/x509"
6 "encoding/pem"
7 "fmt"
8 "time"
9
10 "github.com/go-jose/go-jose/v4"
11 "github.com/go-jose/go-jose/v4/jwt"
12 )
13
14 type TokenSigner struct {
15 PrivateKey string
16 KeyID string
17 Audience string
18 Issuer string
19 Subject string
20 }
21
22 func (input *TokenSigner) GetJWT() (string, error) {
23 signer, err := getRSASigner(input.PrivateKey, input.KeyID)
24 if err != nil {
25 return "", err
26 }
27
28 issuedAt := time.Now()
29 expiresAt := issuedAt.Add(5 * time.Minute)
30
31 payload := Payload{IssuedAt: issuedAt.Unix(), Expiry: expiresAt.Unix(), Audience: input.Audience, Issuer: input.Issuer, Subject: input.Subject}
32 token, err := payload.buildToken(&signer)
33
34 return token, err
35 }
36
37 func getRSASigner(privateKey, keyID string) (jose.Signer, error) {
38 parsedKey, err := parseRSAKey(privateKey)
39 if err != nil {
40 return nil, err
41 }
42
43 key := jose.SigningKey{Algorithm: jose.RS256, Key: parsedKey}
44
45 signerOpts := jose.SignerOptions{}
46 signerOpts.WithType("JWT")
47 signerOpts.WithHeader("kid", keyID)
48
49 rsaSigner, err := jose.NewSigner(key, &signerOpts)
50 if err != nil {
51 return nil, fmt.Errorf("failed to create JWS RSA256 signer: %w", err)
52 }
53
54 return rsaSigner, nil
55 }
56
57 type Payload struct {
58 IssuedAt int64 `json:"iat"`
59 Expiry int64 `json:"exp"`
60 Audience string `json:"aud"`
61 Issuer string `json:"iss"`
62 Subject string `json:"sub"`
63 }
64
65 func (payload *Payload) buildToken(signer *jose.Signer) (string, error) {
66 builder := jwt.Signed(*signer).Claims(payload)
67
68 token, err := builder.Serialize()
69 if err != nil {
70 return "", fmt.Errorf("failed to build JWT: %w", err)
71 }
72
73 return token, nil
74 }
75
76 func parseRSAKey(pemString string) (*rsa.PrivateKey, error) {
77 block, _ := pem.Decode([]byte(pemString))
78
79 key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
80 if err != nil {
81 return nil, fmt.Errorf("failed to parse private key: %w", err)
82 }
83
84 return key, nil
85 }
86