CreateClientAssertion creates a JWT token for client authentication with the specified lifetime.
(alg jwa.SignatureAlgorithm, signingKey, clientID, audience string)
| 344 | |
| 345 | // CreateClientAssertion creates a JWT token for client authentication with the specified lifetime. |
| 346 | func CreateClientAssertion(alg jwa.SignatureAlgorithm, signingKey, clientID, audience string) (string, error) { |
| 347 | key, err := jwk.ParseKey([]byte(signingKey), jwk.WithPEM(true)) |
| 348 | if err != nil { |
| 349 | return "", fmt.Errorf("failed to parse signing key: %w", err) |
| 350 | } |
| 351 | |
| 352 | // Verify that the key type is compatible with the algorithm. |
| 353 | if key.KeyType() != "RSA" { |
| 354 | return "", fmt.Errorf("%s algorithm requires an RSA key, but got %s", alg, key.KeyType()) |
| 355 | } |
| 356 | |
| 357 | now := time.Now() |
| 358 | |
| 359 | token, err := jwt.NewBuilder(). |
| 360 | IssuedAt(now). |
| 361 | NotBefore(now). |
| 362 | Subject(clientID). |
| 363 | JwtID(uuid.NewString()). |
| 364 | Issuer(clientID). |
| 365 | Audience([]string{audience}). |
| 366 | Expiration(now.Add(2 * time.Minute)). |
| 367 | Build() |
| 368 | if err != nil { |
| 369 | return "", fmt.Errorf("failed to build JWT: %w", err) |
| 370 | } |
| 371 | |
| 372 | signedToken, err := jwt.Sign(token, jwt.WithKey(alg, key)) |
| 373 | if err != nil { |
| 374 | return "", fmt.Errorf("failed to sign JWT: %w", err) |
| 375 | } |
| 376 | |
| 377 | return string(signedToken), nil |
| 378 | } |