Files
vw-api/internal/auth/middleware.go
T
Thijs Herman 059f23af2a chore: fix module path to match GitHub URL, update Makefile GHCR path
- Module: github.com/thijsherman → github.com/Turbootzz
- Makefile: turboot/ → ghcr.io/turbootzz/
- Added docker-push-tag target
2026-02-20 18:18:13 +00:00

56 lines
1.7 KiB
Go

// Package auth provides API key authentication middleware
package auth
import (
"crypto/subtle"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/Turbootzz/vaultwarden-api/pkg/logger"
)
// Middleware creates an authentication middleware for API key validation
func Middleware(apiKey string) fiber.Handler {
return func(c *fiber.Ctx) error {
// Get the Authorization header
authHeader := c.Get("Authorization")
if authHeader == "" {
logger.Warn.Println("Missing Authorization header")
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "missing authorization header",
})
}
// Expected format: "Bearer <API_KEY>"
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
logger.Warn.Println("Invalid Authorization header format")
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "invalid authorization header format",
})
}
providedKey := parts[1]
// Use constant-time comparison to prevent timing attacks
if !secureCompare(providedKey, apiKey) {
logger.Warn.Printf("Invalid API key from IP: %s", c.IP())
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "invalid api key",
})
}
// Authentication successful
return c.Next()
}
}
// secureCompare performs a constant-time comparison of two strings
// This prevents timing attacks that could be used to guess the API key
func secureCompare(a, b string) bool {
// If lengths differ, still perform comparison to maintain constant time
// Use subtle.ConstantTimeCompare which returns 1 if equal, 0 otherwise
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}