CreateIDToken util to create the OIDC ID token JWT, based on user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT. See the in-function block comment for the at_hash / c_hash / nonce emission rules per OIDC Core §3.1.3.6 / §3.2.2.10.
(cfg *AuthTokenConfig)
| 423 | // See the in-function block comment for the at_hash / c_hash / nonce |
| 424 | // emission rules per OIDC Core §3.1.3.6 / §3.2.2.10. |
| 425 | func (p *provider) CreateIDToken(cfg *AuthTokenConfig) (string, int64, error) { |
| 426 | expiryBound, err := utils.ParseDurationInSeconds(cfg.ExpireTime) |
| 427 | if err != nil { |
| 428 | expiryBound = time.Minute * 30 |
| 429 | } |
| 430 | expiresAt := time.Now().Add(expiryBound).Unix() |
| 431 | resUser := cfg.User.AsAPIUser() |
| 432 | userBytes, _ := json.Marshal(&resUser) |
| 433 | var userMap map[string]interface{} |
| 434 | _ = json.Unmarshal(userBytes, &userMap) |
| 435 | |
| 436 | customClaims := jwt.MapClaims{ |
| 437 | "iss": cfg.HostName, |
| 438 | "aud": p.config.ClientID, |
| 439 | "sub": cfg.User.ID, |
| 440 | "exp": expiresAt, |
| 441 | "iat": time.Now().Unix(), |
| 442 | "token_type": constants.TokenTypeIdentityToken, |
| 443 | "allowed_roles": strings.Split(cfg.User.Roles, ","), |
| 444 | "login_method": cfg.LoginMethod, |
| 445 | p.config.JWTRoleClaim: cfg.Roles, |
| 446 | } |
| 447 | // OIDC Core §3.1.3.6 / §3.2.2.10: |
| 448 | // at_hash REQUIRED whenever the response includes an access_token |
| 449 | // in the same flow. CreateAuthToken always issues an |
| 450 | // access_token, so cfg.AtHash is always populated. |
| 451 | // c_hash REQUIRED only in hybrid flows that return both code |
| 452 | // and id_token. Set by the /authorize hybrid dispatch |
| 453 | // when cfg.Code is populated. |
| 454 | // nonce MUST be echoed whenever the auth request supplied one, |
| 455 | // regardless of flow. |
| 456 | if cfg.AtHash != "" { |
| 457 | customClaims["at_hash"] = cfg.AtHash |
| 458 | } |
| 459 | if cfg.CodeHash != "" { |
| 460 | customClaims["c_hash"] = cfg.CodeHash |
| 461 | } |
| 462 | // OIDC Core §3.1.3.3: the nonce claim MUST echo the value from the |
| 463 | // original authorize request. OIDCNonce carries that value when the |
| 464 | // token is issued via the token endpoint (code flow). For implicit |
| 465 | // flows the caller sets Nonce directly. |
| 466 | idTokenNonce := cfg.OIDCNonce |
| 467 | if idTokenNonce == "" { |
| 468 | idTokenNonce = cfg.Nonce |
| 469 | } |
| 470 | if idTokenNonce != "" { |
| 471 | customClaims["nonce"] = idTokenNonce |
| 472 | } |
| 473 | // OIDC Core §2: auth_time — Unix seconds. Default to now if caller |
| 474 | // did not supply a session-level auth timestamp (backward compat). |
| 475 | authTime := cfg.AuthTime |
| 476 | if authTime == 0 { |
| 477 | authTime = time.Now().Unix() |
| 478 | } |
| 479 | customClaims["auth_time"] = authTime |
| 480 | |
| 481 | // OIDC Core §2: amr — Authentication Methods Reference array. Omit |
| 482 | // the claim for unknown login methods rather than emit an empty array. |
no test coverage detected