security

package module
v0.0.0-...-cbd040c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 19, 2025 License: MIT Imports: 15 Imported by: 0

README

WebFram Security Middlewares

This package provides configurable middleware for implementing various OpenAPI v3.2.0 security schemes in WebFram applications.

Available Middlewares

HTTP Basic Authentication

Enforces HTTP Basic Authentication as defined in RFC 7617.

config := security.BasicAuthConfig{
    Authenticator: func(username, password string) bool {
        // Validate credentials
        return username == "admin" && password == "secret"
    },
    Realm: "MyApp",
}

mux.Use(security.BasicAuth(config))
HTTP Digest Authentication

Enforces HTTP Digest Authentication as defined in RFC 7616.

config := security.DigestAuthConfig{
    Realm: "MyApp",
    PasswordGetter: func(username, realm string) (password string, ok bool) {
        // Return password for user
        if username == "admin" {
            return "secret", true
        }
        return "", false
    },
    NonceTTL: 30 * time.Minute,
}

mux.Use(security.DigestAuth(config))
HTTP Bearer Token Authentication

Enforces Bearer Token Authentication (commonly used for JWT).

config := security.BearerAuthConfig{
    Authenticator: func(token string) bool {
        // Validate JWT token
        return validateJWT(token)
    },
}

mux.Use(security.BearerAuth(config))
API Key Authentication

Supports API keys in headers, query parameters, or cookies.

config := security.APIKeyAuthConfig{
    KeyName: "X-API-Key",
    In:      "header", // "header", "query", or "cookie"
    Authenticator: func(key string) bool {
        // Validate API key
        return key == "valid-key"
    },
}

mux.Use(security.APIKeyAuth(config))
OAuth 2.0 Authentication

The OAuth2 middlewares support all major OAuth2 flows as defined in RFC 6749.

Authorization Code Flow

For web applications that can securely store client secrets.

config := security.OAuth2AuthorizationCodeConfig{
    OAuth2BaseConfig: security.OAuth2BaseConfig{
        ClientID:     "your-client-id",
        TokenURL:     "https://auth.example.com/oauth/token",
        Scopes:       []string{"read", "write"},
        TokenValidator: func(token string) bool {
            return validateOAuth2Token(token)
        },
        UnauthorizedHandler: nil,
        RefreshBuffer: 5 * time.Minute, // Refresh tokens 5 minutes before expiry
    },
    ClientSecret: "your-client-secret",
    AuthorizationURL: "https://auth.example.com/oauth/authorize",
    RedirectURL:      "https://yourapp.com/oauth/callback",
    StateStore: func(state string) (redirectURL string, ok bool) {
        // Store/retrieve state for CSRF protection
        return "/", true
    },
    TokenStore: func(sessionID string) (*security.OAuth2Token, bool) {
        // Store/retrieve tokens by session
        return nil, false
    },
    SessionIDExtractor: func(r *http.Request) string {
        // Extract session ID from request
        return "session-id"
    },
    // Optional: Enable PKCE for enhanced security (recommended for public clients)
    PKCE: &security.OAuth2PKCEConfig{
        CodeVerifierStore: func(state string) (codeVerifier string, ok bool) {
            // Store/retrieve PKCE code verifier by state
            return getStoredVerifier(state)
        },
        ChallengeMethod: security.PKCES256, // or security.PKCEPlain
    },
}

mux.Use(security.OAuth2AuthorizationCodeAuth(config))

PKCE (Proof Key for Code Exchange): When enabled, PKCE protects against authorization code interception attacks by requiring a code verifier during token exchange. Use PKCES256 for production (recommended) or PKCEPlain for compatibility.

Automatic Token Refresh: Tokens are automatically refreshed when they expire or are close to expiring (based on RefreshBuffer). The middleware handles refresh token storage and validation.

Implicit Flow

For single-page applications (SPAs) where tokens are returned directly.

config := security.OAuth2ImplicitConfig{
    OAuth2BaseConfig: security.OAuth2BaseConfig{
        ClientID:     "your-client-id",
        TokenURL:     "https://auth.example.com/oauth/token",
        Scopes:       []string{"read"},
        TokenValidator: func(token string) bool {
            return validateOAuth2Token(token)
        },
        UnauthorizedHandler: nil,
        RefreshBuffer: 5 * time.Minute, // Refresh tokens 5 minutes before expiry
    },
    AuthorizationURL: "https://auth.example.com/oauth/authorize",
    RedirectURL:      "https://yourapp.com/oauth/callback",
    StateStore: func(state string) (redirectURL string, ok bool) {
        // Store/retrieve state for CSRF protection
        return "/", true
    },
}

mux.Use(security.OAuth2ImplicitAuth(config))
Device Authorization Grant Flow

For devices without browsers or keyboards (IoT, smart TVs, etc.).

config := security.OAuth2DeviceConfig{
    OAuth2BaseConfig: security.OAuth2BaseConfig{
        ClientID:     "your-client-id",
        TokenURL:     "https://auth.example.com/oauth/token",
        Scopes:       []string{"read"},
        TokenValidator: func(token string) bool {
            return validateOAuth2Token(token)
        },
        UnauthorizedHandler: nil,
        RefreshBuffer: 5 * time.Minute, // Refresh tokens 5 minutes before expiry
    },
}

mux.Use(security.OAuth2DeviceAuth(config))

Device Flow Usage:

  1. Device makes POST request with ?request_device_code=true to get user code
  2. User visits verification URI and enters the code
  3. Device polls with ?device_code=... until authorization completes
Client Credentials Flow

For service-to-service authentication.

config := security.OAuth2ClientCredentialsConfig{
    OAuth2BaseConfig: security.OAuth2BaseConfig{
        ClientID:     "your-client-id",
        TokenURL:     "https://auth.example.com/oauth/token",
        Scopes:       []string{"read"},
        TokenValidator: func(token string) bool {
            return validateOAuth2Token(token)
        },
        UnauthorizedHandler: nil,
        RefreshBuffer: 5 * time.Minute, // Refresh tokens 5 minutes before expiry
    },
    ClientSecret: "your-client-secret",
}

mux.Use(security.OAuth2ClientCredentialsAuth(config))
OAuth2 Configuration Options

All OAuth2 flows share common configuration through OAuth2BaseConfig:

  • RefreshBuffer: Time buffer before token expiration to trigger automatic refresh (default: 5 minutes). Tokens are refreshed when they expire or are within this buffer period.
  • TokenValidator: Function to validate access tokens (opaque tokens for API authorization)
  • UnauthorizedHandler: Custom handler for authentication failures
  • Scopes: Requested OAuth2 scopes
  • ClientID: OAuth2 client identifier

Token Validator Types:

  • OAuth2 TokenValidator: Validates access tokens (used for API authorization)
  • OpenID Connect TokenValidator: Validates ID tokens (JWTs containing user identity information)

Automatic Token Refresh: When TokenStore and SessionIDExtractor are configured, tokens are automatically refreshed using refresh tokens before they expire, providing seamless authentication for users.

Token Validation with Scope Checking

For advanced token validation that checks OAuth2 scopes, you can create scope-aware validators using closures:

// Scope-aware validator using token introspection
func createScopeValidator(requiredScopes []string, tokenIntrospector func(string) (map[string]interface{}, error)) func(string) bool {
    return func(token string) bool {
        claims, err := tokenIntrospector(token)
        if err != nil {
            return false
        }
        
        tokenScopes, ok := claims["scope"].([]interface{})
        if !ok {
            return false
        }
        
        var scopes []string
        for _, scope := range tokenScopes {
            if s, ok := scope.(string); ok {
                scopes = append(scopes, s)
            }
        }
        
        return hasAllScopes(scopes, requiredScopes)
    }
}

func hasAllScopes(tokenScopes, requiredScopes []string) bool {
    scopeMap := make(map[string]bool)
    for _, scope := range tokenScopes {
        scopeMap[scope] = true
    }
    
    for _, required := range requiredScopes {
        if !scopeMap[required] {
            return false
        }
    }
    return true
}

// Usage with Authorization Code flow
config := security.OAuth2AuthorizationCodeConfig{
    OAuth2BaseConfig: security.OAuth2BaseConfig{
        ClientID:     "your-client-id",
        TokenURL:     "https://auth.example.com/oauth/token",
        Scopes:       []string{"read", "write", "profile"},
        TokenValidator: createScopeValidator(
            []string{"read"}, // Require at least 'read' scope
            func(token string) (map[string]interface{}, error) {
                // Your token introspection logic
                return introspectToken(token)
            },
        ),
        RefreshBuffer: 5 * time.Minute,
    },
    ClientSecret: "your-client-secret",
    AuthorizationURL: "https://auth.example.com/oauth/authorize",
    RedirectURL:      "https://yourapp.com/oauth/callback",
}

mux.Use(security.OAuth2AuthorizationCodeAuth(config))
JWT-Based Scope Validation
import "github.com/golang-jwt/jwt/v5"

func createJWTValidator(requiredScopes []string, jwtSecret []byte) func(string) bool {
    return func(tokenString string) bool {
        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
            return jwtSecret, nil
        })
        
        if err != nil || !token.Valid {
            return false
        }
        
        claims, ok := token.Claims.(jwt.MapClaims)
        if !ok {
            return false
        }
        
        var tokenScopes []string
        if scopeInterface, exists := claims["scope"]; exists {
            switch scopes := scopeInterface.(type) {
            case []interface{}:
                for _, scope := range scopes {
                    if s, ok := scope.(string); ok {
                        tokenScopes = append(tokenScopes, s)
                    }
                }
            case string:
                tokenScopes = strings.Split(scopes, " ")
            }
        }
        
        return hasAllScopes(tokenScopes, requiredScopes)
    }
}
Route-Specific Scope Validation

For granular access control, combine OAuth2 middleware with route-specific scope checking:

// RequireAllScopes requires ALL specified scopes (AND logic)
func RequireAllScopes(requiredScopes ...string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            token, ok := r.Context().Value(security.OAuth2TokenKey{}).(*security.OAuth2Token)
            if !ok {
                http.Error(w, "No OAuth2 token in context", http.StatusUnauthorized)
                return
            }
            
            tokenScopes := strings.Split(token.Scope, " ")
            if !hasAllScopes(tokenScopes, requiredScopes) {
                http.Error(w, "Insufficient scopes", http.StatusForbidden)
                return
            }
            
            next.ServeHTTP(w, r)
        })
    }
}

// RequireAnyScopes requires ANY of the specified scopes (OR logic)
func RequireAnyScopes(requiredScopes ...string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            token, ok := r.Context().Value(security.OAuth2TokenKey{}).(*security.OAuth2Token)
            if !ok {
                http.Error(w, "No OAuth2 token in context", http.StatusUnauthorized)
                return
            }
            
            tokenScopes := strings.Split(token.Scope, " ")
            if !hasAnyScopes(tokenScopes, requiredScopes) {
                http.Error(w, "Insufficient scopes", http.StatusForbidden)
                return
            }
            
            next.ServeHTTP(w, r)
        })
    }
}

// Usage with OAuth2 middleware
mux.Use(security.OAuth2AuthorizationCodeAuth(oauthConfig))

// Require ALL scopes (user must have both "read" AND "users")
readUsers := security.RequireAllScopes("read", "users")(http.HandlerFunc(listUsers))

// Require ANY scope (user must have either "write" OR "admin")
writeUsers := security.RequireAnyScopes("write", "admin")(http.HandlerFunc(createUser))

// Require specific admin scope
adminPanel := security.RequireAllScopes("admin")(http.HandlerFunc(adminDashboard))

mux.HandleFunc("GET /users", readUsers.ServeHTTP)
mux.HandleFunc("POST /users", writeUsers.ServeHTTP)
mux.HandleFunc("GET /admin", adminPanel.ServeHTTP)

Scope Logic:

  • RequireAllScopes("read", "users"): Token must have BOTH "read" AND "users" scopes
  • RequireAnyScopes("write", "admin"): Token must have EITHER "write" OR "admin" scope (or both)
Token Validation Only

For validating Bearer tokens when OAuth2 flow is handled elsewhere.

config := security.OAuth2TokenConfig{
    TokenValidator: func(token string) bool {
        return validateOAuth2Token(token)
    },
    UnauthorizedHandler: nil,
}

mux.Use(security.OAuth2TokenAuth(config))
OpenID Connect Authentication

Validates OpenID Connect ID tokens (JWTs containing user identity information like user ID, email, and profile data). Supports both simple token validation and full authentication flow with redirects.

Simple Token Validation

For validating existing ID tokens (when authentication is handled elsewhere):

config := security.OpenIDConnectAuthConfig{
    TokenValidator: func(token string) bool {
        // Validate OIDC ID token (JWT)
        return validateOIDCToken(token)
    },
}

mux.Use(security.OpenIDConnectAuth(config))
Full Authentication Flow

For web applications that need to redirect users to authenticate:

config := security.OpenIDConnectAuthConfig{
    IssuerURL:       "https://accounts.google.com",
    ClientID:        "your-client-id",
    ClientSecret:    "your-client-secret", 
    RedirectURL:     "https://yourapp.com/oidc/callback",
    Scopes:          []string{"openid", "profile", "email"},
    TokenValidator: func(token string) bool {
        return validateOIDCToken(token)
    },
    StateStore: func(state string) (redirectURL string, ok bool) {
        // Store/retrieve state for CSRF protection
        return "/", true
    },
}

mux.Use(security.OpenIDConnectAuth(config))

The middleware automatically detects which mode to use based on whether redirect fields are configured.

Mutual TLS Authentication

Enforces client certificate authentication.

config := security.MutualTLSAuthConfig{
    CertificateValidator: func(cert *x509.Certificate) bool {
        // Validate client certificate
        return cert.Subject.CommonName == "valid-client"
    },
}

mux.Use(security.MutualTLSAuth(config))

Configuration Options

All middlewares support:

  • Authenticator/Validator functions: Custom logic for credential validation
  • UnauthorizedHandler: Optional custom handler for failed authentication
  • Scheme-specific options: Realm, key names, TTL, etc.

Usage with WebFram

package main

import (
    "github.com/bondowe/webfram"
    "github.com/bondowe/webfram/security"
)

func main() {
    app := webfram.NewServeMux()

    // Apply authentication middleware
    app.Use(security.BasicAuth(security.BasicAuthConfig{
        Authenticator: authenticateUser,
        Realm: "MyApp",
    }))

    // Protected routes
    app.HandleFunc("GET /api/users", listUsers)
    app.HandleFunc("POST /api/users", createUser)

    webfram.ListenAndServe(":8080", app, nil)
}

func authenticateUser(username, password string) bool {
    // Implement authentication logic
    return true // or false
}

Security Considerations

  • Always use HTTPS in production
  • Implement proper password hashing for basic auth
  • Validate tokens securely for bearer/OAuth2/OIDC
  • Regularly rotate API keys and nonces
  • Use strong certificate validation for mutual TLS

OpenAPI Integration

These middlewares work seamlessly with WebFram's OpenAPI documentation generation. Configure security requirements in your operation configs:

mux.HandleFunc("GET /users", listUsers).WithOperationConfig(&webfram.OperationConfig{
    Security: []map[string][]string{
        {"BasicAuth": {}},
    },
})

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func APIKeyAuth

func APIKeyAuth(config APIKeyAuthConfig) func(http.Handler) http.Handler

APIKeyAuth returns a middleware that enforces API Key Authentication.

func BasicAuth

func BasicAuth(config BasicAuthConfig) func(http.Handler) http.Handler

BasicAuth returns a middleware that enforces HTTP Basic Authentication.

func BearerAuth

func BearerAuth(config BearerAuthConfig) func(http.Handler) http.Handler

BearerAuth returns a middleware that enforces HTTP Bearer Token Authentication.

func DigestAuth

func DigestAuth(config DigestAuthConfig) func(http.Handler) http.Handler

DigestAuth returns a middleware that enforces HTTP Digest Authentication.

func MutualTLSAuth

func MutualTLSAuth(config MutualTLSAuthConfig) func(http.Handler) http.Handler

MutualTLSAuth returns a middleware that enforces Mutual TLS Authentication.

func OAuth2AuthorizationCodeAuth

func OAuth2AuthorizationCodeAuth(config OAuth2AuthorizationCodeConfig) func(http.Handler) http.Handler

OAuth2AuthorizationCodeAuth returns middleware for OAuth2 Authorization Code flow.

func OAuth2ClientCredentialsAuth

func OAuth2ClientCredentialsAuth(config OAuth2ClientCredentialsConfig) func(http.Handler) http.Handler

OAuth2ClientCredentialsAuth returns middleware for OAuth2 Client Credentials flow.

func OAuth2DeviceAuth

func OAuth2DeviceAuth(config OAuth2DeviceConfig) func(http.Handler) http.Handler

OAuth2DeviceAuth returns middleware for OAuth2 Device Authorization Grant flow.

func OAuth2ImplicitAuth

func OAuth2ImplicitAuth(config OAuth2ImplicitConfig) func(http.Handler) http.Handler

OAuth2ImplicitAuth returns middleware for OAuth2 Implicit flow.

func OAuth2TokenAuth

func OAuth2TokenAuth(config OAuth2TokenConfig) func(http.Handler) http.Handler

OAuth2TokenAuth returns middleware that validates OAuth2 Bearer tokens.

func OpenIDConnectAuth

func OpenIDConnectAuth(config OpenIDConnectAuthConfig) func(http.Handler) http.Handler

OpenIDConnectAuth returns a middleware that enforces OpenID Connect Authentication. If redirect fields are configured, it will redirect users to authenticate. Otherwise, it validates existing Bearer tokens.

func RequireAllScopes

func RequireAllScopes(requiredScopes ...string) func(http.Handler) http.Handler

RequireAllScopes returns middleware that requires ALL of the specified scopes. The token must have every scope in the requiredScopes slice.

func RequireAnyScopes

func RequireAnyScopes(requiredScopes ...string) func(http.Handler) http.Handler

RequireAnyScopes returns middleware that requires ANY of the specified scopes. The token must have at least one scope from the requiredScopes slice.

Types

type APIKeyAuthConfig

type APIKeyAuthConfig struct {
	// KeyValidator is called with the API key, should return true if valid
	KeyValidator func(key string) bool
	// KeyName is the name of the API key parameter (default: "api_key")
	KeyName string
	// KeyLocation specifies where to look for the API key: "header", "query", "cookie"
	KeyLocation string
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler
}

APIKeyAuthConfig holds configuration for API key authentication middleware.

type BasicAuthConfig

type BasicAuthConfig struct {
	// Authenticator is called with username and password, should return true if valid
	Authenticator func(username, password string) bool
	// Realm is the authentication realm (default: "Restricted")
	Realm string
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler
}

BasicAuthConfig holds configuration for basic authentication middleware.

type BearerAuthConfig

type BearerAuthConfig struct {
	// TokenValidator is called with the bearer token, should return true if valid
	TokenValidator func(token string) bool
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler
}

BearerAuthConfig holds configuration for bearer token authentication middleware.

type Config

type Config struct {
	// AllowAnonymousAuth indicates whether anonymous (unauthenticated) access is allowed.
	AllowAnonymousAuth bool
	// APIKeyAuth configures API Key authentication settings.
	APIKeyAuth *APIKeyAuthConfig
	// BasicAuth configures Basic authentication settings.
	BasicAuth *BasicAuthConfig
	// BearerAuth configures Bearer authentication settings.
	BearerAuth *BearerAuthConfig
	// DigestAuth configures Digest authentication settings.
	DigestAuth *DigestAuthConfig
	// MutualTLSAuthConfig configures Mutual TLS authentication settings.
	MutualTLSAuth *MutualTLSAuthConfig
	// OAuth2AuthorizationCode configures OAuth2 Authorization Code flow settings.
	OAuth2AuthorizationCode *OAuth2AuthorizationCodeConfig
	// OAuth2ClientCredentials configures OAuth2 Client Credentials flow settings.
	OAuth2ClientCredentials *OAuth2ClientCredentialsConfig
	// OAuth2Device configures OAuth2 Device Code flow settings.
	OAuth2Device *OAuth2DeviceConfig
	// OAuth2Implicit configures OAuth2 Implicit flow settings.
	OAuth2Implicit *OAuth2ImplicitConfig
	// OpenIDConnectAuth configures OpenID Connect authentication settings.
	OpenIDConnectAuth *OpenIDConnectAuthConfig
}

type DigestAuthConfig

type DigestAuthConfig struct {
	// Realm is the authentication realm
	Realm string
	// PasswordGetter is called with username and realm, should return the password and true if user exists
	PasswordGetter func(username, realm string) (password string, ok bool)
	// NonceTTL is the time-to-live for nonces (default 30 minutes)
	NonceTTL time.Duration
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler
}

DigestAuthConfig holds configuration for digest authentication middleware.

type MutualTLSAuthConfig

type MutualTLSAuthConfig struct {
	// CertificateValidator is called with the client certificate, should return true if valid
	CertificateValidator func(cert *x509.Certificate) bool
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler
}

MutualTLSAuthConfig holds configuration for mutual TLS authentication middleware.

type OAuth2AuthorizationCodeConfig

type OAuth2AuthorizationCodeConfig struct {
	OAuth2BaseConfig
	// ClientSecret is the OAuth2 client secret
	ClientSecret string
	// AuthorizationURL is the OAuth2 authorization endpoint
	AuthorizationURL string
	// RedirectURL is the OAuth2 redirect URI
	RedirectURL string
	// StateStore stores/retrieves OAuth2 state parameters
	StateStore func(state string) (redirectURL string, ok bool)
	// TokenStore stores/retrieves OAuth2 tokens
	TokenStore func(sessionID string) (*OAuth2Token, bool)
	// SessionIDExtractor extracts session ID from request
	SessionIDExtractor func(r *http.Request) string
	// PKCE configuration (optional)
	PKCE *OAuth2PKCEConfig
}

OAuth2AuthorizationCodeConfig holds configuration for Authorization Code flow.

type OAuth2BaseConfig

type OAuth2BaseConfig struct {
	// ClientID is the OAuth2 client identifier
	ClientID string
	// TokenURL is the OAuth2 token endpoint
	TokenURL string
	// Scopes are the requested OAuth2 scopes
	Scopes []string
	// TokenValidator validates access tokens
	TokenValidator func(token string) bool
	// UnauthorizedHandler is called when authentication fails
	UnauthorizedHandler http.Handler
	// RefreshBuffer is the time buffer before expiration to trigger refresh (default: 5 minutes)
	RefreshBuffer time.Duration
}

OAuth2BaseConfig holds common OAuth2 configuration fields.

type OAuth2ClientCredentialsConfig

type OAuth2ClientCredentialsConfig struct {
	OAuth2BaseConfig
	// ClientSecret is the OAuth2 client secret
	ClientSecret string
	// TokenStore stores/retrieves OAuth2 tokens (optional for caching)
	TokenStore func(sessionID string) (*OAuth2Token, bool)
	// SessionIDExtractor extracts session ID from request (optional)
	SessionIDExtractor func(r *http.Request) string
}

OAuth2ClientCredentialsConfig holds configuration for Client Credentials flow.

type OAuth2Config

type OAuth2Config struct {
	// ClientID is the OAuth2 client identifier
	ClientID string
	// ClientSecret is the OAuth2 client secret
	ClientSecret string
	// AuthorizationURL is the OAuth2 authorization endpoint
	AuthorizationURL string
	// TokenURL is the OAuth2 token endpoint
	TokenURL string
	// RedirectURL is the OAuth2 redirect URI
	RedirectURL string
	// Scopes are the requested OAuth2 scopes
	Scopes []string
	// TokenValidator validates access tokens
	TokenValidator func(token string) bool
	// StateStore stores/retrieves OAuth2 state parameters
	StateStore func(state string) (redirectURL string, ok bool)
	// TokenStore stores/retrieves OAuth2 tokens
	TokenStore func(sessionID string) (*OAuth2Token, bool)
	// SessionIDExtractor extracts session ID from request
	SessionIDExtractor func(r *http.Request) string
	// UnauthorizedHandler is called when authentication fails
	UnauthorizedHandler http.Handler
	// RefreshBuffer is the time buffer before expiration to trigger refresh (default: 5 minutes)
	RefreshBuffer time.Duration
}

OAuth2Config holds common OAuth2 configuration (deprecated - use flow-specific configs).

type OAuth2DeviceCode

type OAuth2DeviceCode struct {
	DeviceCode              string `json:"device_code"`
	UserCode                string `json:"user_code"`
	VerificationURI         string `json:"verification_uri"`
	VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
	ExpiresIn               int    `json:"expires_in"`
	Interval                int    `json:"interval,omitempty"`
}

OAuth2DeviceCode represents a device authorization response.

type OAuth2DeviceConfig

type OAuth2DeviceConfig struct {
	OAuth2BaseConfig
}

OAuth2DeviceConfig holds configuration for Device Authorization Grant flow.

type OAuth2FlowType

type OAuth2FlowType string

OAuth2FlowType represents the different OAuth2 flow types.

const (
	OAuth2FlowAuthorizationCode OAuth2FlowType = "authorization_code"
	OAuth2FlowImplicit          OAuth2FlowType = "implicit"
	OAuth2FlowDevice            OAuth2FlowType = "device_code"
	OAuth2FlowClientCredentials OAuth2FlowType = "client_credentials"
)

type OAuth2ImplicitConfig

type OAuth2ImplicitConfig struct {
	OAuth2BaseConfig
	// AuthorizationURL is the OAuth2 authorization endpoint
	AuthorizationURL string
	// RedirectURL is the OAuth2 redirect URI
	RedirectURL string
	// StateStore stores/retrieves OAuth2 state parameters
	StateStore func(state string) (redirectURL string, ok bool)
}

OAuth2ImplicitConfig holds configuration for Implicit flow.

type OAuth2PKCEConfig

type OAuth2PKCEConfig struct {
	// CodeVerifierStore stores/retrieves PKCE code verifiers by state
	CodeVerifierStore func(state string) (codeVerifier string, ok bool)
	// ChallengeMethod specifies the PKCE challenge method ("S256" or "plain")
	ChallengeMethod PKCEChallengeMethod
}

OAuth2PKCEConfig holds PKCE (Proof Key for Code Exchange) configuration.

type OAuth2Token

type OAuth2Token struct {
	AccessToken  string    `json:"access_token"`
	TokenType    string    `json:"token_type"`
	ExpiresIn    int       `json:"expires_in"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	Scope        string    `json:"scope,omitempty"`
	IssuedAt     time.Time `json:"issued_at,omitempty"`  // When token was issued
	ExpiresAt    time.Time `json:"expires_at,omitempty"` // When token expires
}

OAuth2Token represents an OAuth2 token response with expiration tracking.

func (*OAuth2Token) IsExpired

func (t *OAuth2Token) IsExpired(buffer time.Duration) bool

IsExpired checks if the access token is expired with a buffer.

func (*OAuth2Token) NeedsRefresh

func (t *OAuth2Token) NeedsRefresh(buffer time.Duration) bool

NeedsRefresh checks if the token should be refreshed (expired or close to expiring).

type OAuth2TokenConfig

type OAuth2TokenConfig struct {
	// TokenValidator validates access tokens
	TokenValidator func(token string) bool
	// UnauthorizedHandler is called when authentication fails
	UnauthorizedHandler http.Handler
}

OAuth2TokenConfig holds configuration for simple token validation.

type OAuth2TokenKey

type OAuth2TokenKey struct{}

OAuth2TokenKey is the context key for OAuth2 tokens.

type OIDCToken

type OIDCToken struct {
	AccessToken  string    `json:"access_token"`
	TokenType    string    `json:"token_type"`
	IDToken      string    `json:"id_token"`
	ExpiresIn    int       `json:"expires_in"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	Scope        string    `json:"scope,omitempty"`
	IssuedAt     time.Time `json:"issued_at,omitempty"`  // When token was issued
	ExpiresAt    time.Time `json:"expires_at,omitempty"` // When token expires
}

OIDCToken represents an OpenID Connect token response with expiration tracking.

func (*OIDCToken) IsExpired

func (t *OIDCToken) IsExpired(buffer time.Duration) bool

IsExpired checks if the access token is expired with a buffer.

func (*OIDCToken) NeedsRefresh

func (t *OIDCToken) NeedsRefresh(buffer time.Duration) bool

NeedsRefresh checks if the token should be refreshed (expired or close to expiring).

type OIDCTokenKey

type OIDCTokenKey struct{}

OIDCTokenKey is the context key for OIDC tokens.

type OpenIDConnectAuthConfig

type OpenIDConnectAuthConfig struct {
	// TokenValidator validates ID tokens (for simple token validation)
	TokenValidator func(token string) bool
	// UnauthorizedHandler is called when authentication fails (optional)
	UnauthorizedHandler http.Handler

	// Fields for full OIDC flow (optional - if provided, enables redirect)
	IssuerURL    string   // OIDC provider issuer URL
	ClientID     string   // OIDC client ID
	ClientSecret string   // OIDC client secret
	RedirectURL  string   // Callback URL
	Scopes       []string // Requested scopes (default: ["openid"])

	// State management (required for redirect flow)
	StateStore func(state string) (redirectURL string, ok bool)
	// Token storage (optional)
	TokenStore         func(sessionID string) (*OIDCToken, bool)
	SessionIDExtractor func(r *http.Request) string
	// RefreshBuffer is the time buffer before expiration to trigger refresh (default: 5 minutes)
	RefreshBuffer time.Duration
}

OpenIDConnectAuthConfig holds configuration for OpenID Connect authentication middleware.

type PKCEChallengeMethod

type PKCEChallengeMethod string

PKCE challenge methods

const (
	PKCES256  PKCEChallengeMethod = "S256"
	PKCEPlain PKCEChallengeMethod = "plain"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL