| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package sts
- import (
- "time"
- "github.com/golang-jwt/jwt/v5"
- )
- // STSSessionClaims represents comprehensive session information embedded in JWT tokens
- // This eliminates the need for separate session storage by embedding all session
- // metadata directly in the token itself - enabling true stateless operation
- type STSSessionClaims struct {
- jwt.RegisteredClaims
- // Session identification
- SessionId string `json:"sid"` // session_id (abbreviated for smaller tokens)
- SessionName string `json:"snam"` // session_name (abbreviated for smaller tokens)
- TokenType string `json:"typ"` // token_type
- // Role information
- RoleArn string `json:"role"` // role_arn
- AssumedRole string `json:"assumed"` // assumed_role_user
- Principal string `json:"principal"` // principal_arn
- // Authorization data
- Policies []string `json:"pol,omitempty"` // policies (abbreviated)
- // Identity provider information
- IdentityProvider string `json:"idp"` // identity_provider
- ExternalUserId string `json:"ext_uid"` // external_user_id
- ProviderIssuer string `json:"prov_iss"` // provider_issuer
- // Request context (optional, for policy evaluation)
- RequestContext map[string]interface{} `json:"req_ctx,omitempty"`
- // Session metadata
- AssumedAt time.Time `json:"assumed_at"` // when role was assumed
- MaxDuration int64 `json:"max_dur,omitempty"` // maximum session duration in seconds
- }
- // NewSTSSessionClaims creates new STS session claims with all required information
- func NewSTSSessionClaims(sessionId, issuer string, expiresAt time.Time) *STSSessionClaims {
- now := time.Now()
- return &STSSessionClaims{
- RegisteredClaims: jwt.RegisteredClaims{
- Issuer: issuer,
- Subject: sessionId,
- IssuedAt: jwt.NewNumericDate(now),
- ExpiresAt: jwt.NewNumericDate(expiresAt),
- NotBefore: jwt.NewNumericDate(now),
- },
- SessionId: sessionId,
- TokenType: TokenTypeSession,
- AssumedAt: now,
- }
- }
- // ToSessionInfo converts JWT claims back to SessionInfo structure
- // This enables seamless integration with existing code expecting SessionInfo
- func (c *STSSessionClaims) ToSessionInfo() *SessionInfo {
- var expiresAt time.Time
- if c.ExpiresAt != nil {
- expiresAt = c.ExpiresAt.Time
- }
- return &SessionInfo{
- SessionId: c.SessionId,
- SessionName: c.SessionName,
- RoleArn: c.RoleArn,
- AssumedRoleUser: c.AssumedRole,
- Principal: c.Principal,
- Policies: c.Policies,
- ExpiresAt: expiresAt,
- IdentityProvider: c.IdentityProvider,
- ExternalUserId: c.ExternalUserId,
- ProviderIssuer: c.ProviderIssuer,
- RequestContext: c.RequestContext,
- }
- }
- // IsValid checks if the session claims are valid (not expired, etc.)
- func (c *STSSessionClaims) IsValid() bool {
- now := time.Now()
- // Check expiration
- if c.ExpiresAt != nil && c.ExpiresAt.Before(now) {
- return false
- }
- // Check not-before
- if c.NotBefore != nil && c.NotBefore.After(now) {
- return false
- }
- // Ensure required fields are present
- if c.SessionId == "" || c.RoleArn == "" || c.Principal == "" {
- return false
- }
- return true
- }
- // GetSessionId returns the session identifier
- func (c *STSSessionClaims) GetSessionId() string {
- return c.SessionId
- }
- // GetExpiresAt returns the expiration time
- func (c *STSSessionClaims) GetExpiresAt() time.Time {
- if c.ExpiresAt != nil {
- return c.ExpiresAt.Time
- }
- return time.Time{}
- }
- // WithRoleInfo sets role-related information in the claims
- func (c *STSSessionClaims) WithRoleInfo(roleArn, assumedRole, principal string) *STSSessionClaims {
- c.RoleArn = roleArn
- c.AssumedRole = assumedRole
- c.Principal = principal
- return c
- }
- // WithPolicies sets the policies associated with this session
- func (c *STSSessionClaims) WithPolicies(policies []string) *STSSessionClaims {
- c.Policies = policies
- return c
- }
- // WithIdentityProvider sets identity provider information
- func (c *STSSessionClaims) WithIdentityProvider(providerName, externalUserId, providerIssuer string) *STSSessionClaims {
- c.IdentityProvider = providerName
- c.ExternalUserId = externalUserId
- c.ProviderIssuer = providerIssuer
- return c
- }
- // WithRequestContext sets request context for policy evaluation
- func (c *STSSessionClaims) WithRequestContext(ctx map[string]interface{}) *STSSessionClaims {
- c.RequestContext = ctx
- return c
- }
- // WithMaxDuration sets the maximum session duration
- func (c *STSSessionClaims) WithMaxDuration(duration time.Duration) *STSSessionClaims {
- c.MaxDuration = int64(duration.Seconds())
- return c
- }
- // WithSessionName sets the session name
- func (c *STSSessionClaims) WithSessionName(sessionName string) *STSSessionClaims {
- c.SessionName = sessionName
- return c
- }
|