You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							154 lines
						
					
					
						
							4.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							154 lines
						
					
					
						
							4.6 KiB
						
					
					
				
								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
							 | 
						|
								}
							 |