Enhance OAuth security configuration and cookie handling

- Add SecureCookie field to TempSecurityConfig and SecurityConfig for better cookie security management.
- Implement SetSecureCookieEnabled and IsSecureCookieEnabled functions to manage secure cookie settings globally.
- Update response handling to utilize secure cookie settings, ensuring compliance with security best practices.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Max 2026-02-04 20:16:24 +08:00
parent 1680d5eefe
commit d7ba22ae8e
7 changed files with 366 additions and 326 deletions

File diff suppressed because one or more lines are too long

View file

@ -93,6 +93,7 @@ func (config *Config) MarshalJSON() ([]byte, error) {
IPBlacklist: config.OAuth.Security.IPBlacklist,
RequireHTTPS: config.OAuth.Security.RequireHTTPS,
DisableUnsecureEndpoints: config.OAuth.Security.DisableUnsecureEndpoints,
SecureCookie: config.OAuth.Security.SecureCookie,
},
Client: TempClientConfig{
DefaultClientType: config.OAuth.Client.DefaultClientType,
@ -215,6 +216,7 @@ func (config *Config) UnmarshalJSON(data []byte) error {
IPBlacklist: tempConfig.OAuth.Security.IPBlacklist,
RequireHTTPS: tempConfig.OAuth.Security.RequireHTTPS,
DisableUnsecureEndpoints: tempConfig.OAuth.Security.DisableUnsecureEndpoints,
SecureCookie: tempConfig.OAuth.Security.SecureCookie,
}
if tempConfig.OAuth.Security.StateParameterLifetime != "" {
if duration, err := parseDuration(tempConfig.OAuth.Security.StateParameterLifetime); err == nil {

View file

@ -179,6 +179,14 @@ func (s *Service) GetStore() store.Store {
return s.store
}
// GetSecurityConfig returns the security configuration for the service
func (s *Service) GetSecurityConfig() types.SecurityConfig {
if s.config == nil {
return types.SecurityConfig{}
}
return s.config.Security
}
// setConfigDefaults sets default values for configuration
func setConfigDefaults(config *Config) error {
// Certificate defaults

View file

@ -575,6 +575,9 @@ type SecurityConfig struct {
IPBlacklist []string `json:"ip_blacklist,omitempty"` // Optional: IP addresses blocked from access (default: [])
RequireHTTPS bool `json:"require_https"` // Optional: Require HTTPS for all endpoints (default: true)
DisableUnsecureEndpoints bool `json:"disable_unsecure_endpoints"` // Optional: Disable non-HTTPS endpoints (default: false)
// Cookie security settings
SecureCookie *bool `json:"secure_cookie,omitempty"` // Optional: Use __Host- prefix and Secure flag for cookies (default: true). Set to false for non-HTTPS dev environments with non-localhost IPs.
}
// TokenClaims represents decoded token claims for both JWT and opaque tokens

View file

@ -21,6 +21,7 @@ import (
"github.com/yaoapp/yao/openapi/oauth"
"github.com/yaoapp/yao/openapi/oauth/acl"
"github.com/yaoapp/yao/openapi/oauth/types"
"github.com/yaoapp/yao/openapi/response"
"github.com/yaoapp/yao/openapi/team"
openapiTrace "github.com/yaoapp/yao/openapi/trace"
"github.com/yaoapp/yao/openapi/user"
@ -63,6 +64,10 @@ func Load(appConfig config.Config) (*OpenAPI, error) {
return nil, err
}
// Set the secure cookie configuration for the response package
// This determines whether to use __Host- prefix and Secure flag for cookies
response.SetSecureCookieEnabled(oauthConfig.Security.SecureCookie)
// Load user configurations
err = user.Load(appConfig)
if err != nil {

View file

@ -8,6 +8,23 @@ import (
"github.com/yaoapp/yao/openapi/oauth/types"
)
// secureCookieEnabled is the global setting for secure cookie behavior
// Default is nil (meaning true/enabled). Set to false to disable __Host- prefix and Secure flag.
// This is set during OAuth initialization based on the secure_cookie config.
var secureCookieEnabled *bool
// SetSecureCookieEnabled sets the global secure cookie setting
// This should be called during OAuth initialization
func SetSecureCookieEnabled(enabled *bool) {
secureCookieEnabled = enabled
}
// IsSecureCookieEnabled returns whether secure cookie is enabled
// Returns true if secureCookieEnabled is nil or true
func IsSecureCookieEnabled() bool {
return secureCookieEnabled == nil || *secureCookieEnabled
}
// Type aliases for OAuth types to simplify usage
type (
// Core response types
@ -202,13 +219,14 @@ type SecureCookieOptions struct {
}
// NewSecureCookieOptions creates a new SecureCookieOptions with secure defaults
// The UseHostPrefix is determined by the secure_cookie configuration in openapi.yao
func NewSecureCookieOptions() *SecureCookieOptions {
return &SecureCookieOptions{
MaxAge: 0, // Session cookie by default
Path: "/", // Root path
Domain: "", // Current domain
SameSite: "Lax", // Default SameSite policy
UseHostPrefix: true, // Use most secure __Host- prefix
MaxAge: 0, // Session cookie by default
Path: "/", // Root path
Domain: "", // Current domain
SameSite: "Lax", // Default SameSite policy
UseHostPrefix: IsSecureCookieEnabled(), // Determined by secure_cookie config
}
}
@ -284,12 +302,15 @@ func SendSecureCookieWithOptions(c *gin.Context, key string, value string, optio
cookiePath := options.Path
cookieDomain := options.Domain
if options.UseHostPrefix {
// Use the global secure cookie setting
useSecureCookie := IsSecureCookieEnabled()
if options.UseHostPrefix && useSecureCookie {
// __Host- prefix: Requires Secure flag, no Domain attribute, Path=/
cookieName = "__Host-" + key
cookiePath = "/" // Must be "/" for __Host- prefix
cookieDomain = "" // Must be empty for __Host- prefix
} else if options.UseSecurePrefix {
} else if options.UseSecurePrefix && useSecureCookie {
// __Secure- prefix: Requires Secure flag, allows Domain and Path
cookieName = "__Secure-" + key
}
@ -319,7 +340,7 @@ func SendSecureCookieWithOptions(c *gin.Context, key string, value string, optio
effectiveMaxAge, // maxAge (calculated from Expires if needed)
cookiePath, // path
cookieDomain, // domain
true, // secure (HTTPS only) - required for security prefixes
useSecureCookie, // secure (HTTPS only) - based on secure_cookie config
true, // httpOnly (prevent XSS access)
)

View file

@ -92,6 +92,7 @@ type TempSecurityConfig struct {
IPBlacklist []string `json:"ip_blacklist,omitempty"`
RequireHTTPS bool `json:"require_https"`
DisableUnsecureEndpoints bool `json:"disable_unsecure_endpoints"`
SecureCookie *bool `json:"secure_cookie,omitempty"`
}
// TempClientConfig represents client configuration with string duration fields