Documentation
¶
Overview ¶
Package basicauth provides HTTP Basic Authentication middleware for celeris.
The middleware parses the Authorization header via the framework's celeris.Context.BasicAuth method, validates credentials via a user-supplied function, and stores the authenticated username in the context store under UsernameKey. Failed authentication returns 401 with a WWW-Authenticate header.
One of Config.Validator, Config.ValidatorWithContext, Config.Users, or Config.HashedUsers is required; omitting all four panics at initialization.
Simple usage with a Users map (auto-generates a constant-time validator):
server.Use(basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "secret",
"user": "pass",
},
}))
Hashed passwords with SHA-256 (avoids storing plaintext):
server.Use(basicauth.New(basicauth.Config{
HashedUsers: map[string]string{
"admin": basicauth.HashPassword("secret"),
},
}))
WARNING: SHA-256 is a fast hash with no work factor. For high-security password storage, use bcrypt, scrypt, or Argon2 via a custom Config.Validator or Config.HashedUsersFunc.
Plugging in bcrypt via HashedUsersFunc:
server.Use(basicauth.New(basicauth.Config{
HashedUsers: map[string]string{
"admin": "$2a$10$...", // bcrypt hash
},
HashedUsersFunc: func(hash, password string) bool {
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
},
}))
Retrieving the Username ¶
Use UsernameFromContext to retrieve the authenticated username from downstream handlers:
name := basicauth.UsernameFromContext(c)
Skipping ¶
Set Config.Skip to bypass the middleware dynamically, or Config.SkipPaths for exact-match path exclusions.
Index ¶
Examples ¶
Constants ¶
const UsernameKey = "basicauth_username"
UsernameKey is the context store key for the authenticated username.
Variables ¶
ErrUnauthorized is returned when authentication fails.
Functions ¶
func HashPassword ¶
HashPassword returns the hex-encoded SHA-256 hash of password. Use this to produce values for Config.HashedUsers.
func New ¶
func New(config ...Config) celeris.HandlerFunc
New creates a basic auth middleware with the given config.
Example ¶
package main
import (
"github.com/goceleris/celeris/middleware/basicauth"
)
func main() {
// Simple static credentials with the Users map.
_ = basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "secret",
"user": "password",
},
})
}
Output:
Example (ContextValidator) ¶
package main
import (
"github.com/goceleris/celeris"
"github.com/goceleris/celeris/middleware/basicauth"
)
func main() {
// Context-aware validator for per-request auth decisions.
_ = basicauth.New(basicauth.Config{
ValidatorWithContext: func(c *celeris.Context, user, _ string) bool {
tenant := c.Header("x-tenant")
return tenant == "acme" && user == "admin"
},
})
}
Output:
Example (HashedUsers) ¶
package main
import (
"github.com/goceleris/celeris/middleware/basicauth"
)
func main() {
// SHA-256 hashed passwords — avoids storing plaintext in source/config.
_ = basicauth.New(basicauth.Config{
HashedUsers: map[string]string{
"admin": basicauth.HashPassword("secret"),
"user": basicauth.HashPassword("password"),
},
})
}
Output:
Example (Validator) ¶
package main
import (
"github.com/goceleris/celeris/middleware/basicauth"
)
func main() {
// Custom validator for dynamic credential checking.
_ = basicauth.New(basicauth.Config{
Validator: func(user, pass string) bool {
// Check against a database or external service.
return user == "admin" && pass == "secret"
},
})
}
Output:
func UsernameFromContext ¶
UsernameFromContext returns the authenticated username from the context store. Returns an empty string if no username was stored (e.g., no auth or skipped).
Types ¶
type Config ¶
type Config struct {
// Skip defines a function to skip this middleware for certain requests.
Skip func(c *celeris.Context) bool
// SkipPaths lists paths to skip (exact match).
SkipPaths []string
// Validator checks credentials. Required if Users is nil -- panics if both are nil.
Validator func(user, pass string) bool
// ValidatorWithContext checks credentials with access to the request context.
// Takes precedence over Validator when set.
ValidatorWithContext func(c *celeris.Context, user, pass string) bool
// Users maps usernames to passwords. When set and Validator is nil,
// a constant-time validator is auto-generated from this map.
Users map[string]string
// HashedUsers maps usernames to hex-encoded SHA-256 password hashes.
// When set and Validator, ValidatorWithContext, and Users are all nil,
// a constant-time validator is auto-generated that SHA-256 hashes the
// incoming password and compares it against the stored hash.
// Use [HashPassword] to produce the hex-encoded hash values.
HashedUsers map[string]string
// HashedUsersFunc, when non-nil, replaces the built-in SHA-256
// comparison used by HashedUsers. It receives the stored hex-encoded
// hash and the plaintext password and returns true if they match.
// This lets callers plug in bcrypt, argon2, or any other password
// hashing algorithm without this package importing those libraries.
//
// IMPORTANT: The function MUST take constant time for any input,
// including empty or invalid hash strings. For bcrypt, this means
// pre-computing a dummy hash (via bcrypt.GenerateFromPassword) and
// comparing against it for unknown users, rather than letting
// bcrypt.CompareHashAndPassword fail instantly on an empty hash.
HashedUsersFunc func(hash, password string) bool
// Realm is the authentication realm. Default: "Restricted".
Realm string
// ErrorHandler handles authentication failures. The err parameter is
// [ErrUnauthorized] for all auth failures.
// Default: 401 with WWW-Authenticate + Cache-Control + Vary headers.
ErrorHandler func(c *celeris.Context, err error) error
}
Config defines the basic auth middleware configuration.