Documentation
¶
Overview ¶
Package basicauth provides HTTP Basic Authentication middleware for celeris.
The middleware parses the Authorization header via celeris.Context.BasicAuth, validates credentials via a user-supplied function, and stores the authenticated username in the context store under UsernameKey. Failed authentication returns 401 with WWW-Authenticate, Cache-Control, and Vary headers.
Exactly one credential source is required; New panics otherwise:
- Config.Users — plaintext map, auto-generates a constant-time HMAC validator.
- Config.HashedUsers + Config.HashedUsersFunc — opaque hash strings with a caller-supplied compare function (bcrypt, argon2id, scrypt, etc.). HashedUsersFunc is mandatory when HashedUsers is set.
- Config.Validator — arbitrary func(user, pass string) bool.
- Config.ValidatorWithContext — same, with request context access.
Minimal usage with a Users map:
server.Use(basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "secret",
},
}))
Use UsernameFromContext to retrieve the authenticated username downstream. Set Config.Skip or Config.SkipPaths to bypass the middleware selectively.
Note: HashPassword (SHA-256) is deprecated and credential-grade only with a modern KDF. Use bcrypt or argon2 via Config.HashedUsersFunc instead.
Documentation ¶
Full guides and examples: https://goceleris.dev/docs/middleware-auth
Index ¶
Examples ¶
Constants ¶
const UsernameKey = "basicauth_username"
UsernameKey is the context store key for the authenticated username.
Variables ¶
ErrUnauthorized is returned when authentication fails. ErrUnauthorized aliases celeris.ErrUnauthorized so cross-package errors.Is checks work.
Functions ¶
func HashPassword ¶
HashPassword returns the hex-encoded SHA-256 hash of password.
DEPRECATED: SHA-256 is not credential-grade — adversaries can crack it at billions of guesses per second on commodity GPUs. Use bcrypt or argon2 with Config.HashedUsersFunc instead. This helper is retained for backwards-compatibility but may be removed in a future major release.
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 opaque hash strings. The format is
// determined by HashedUsersFunc — bcrypt's $2y$..., argon2id's $argon2..,
// scrypt, etc. HashedUsersFunc is REQUIRED whenever HashedUsers is
// non-empty; basicauth.New() panics otherwise. There is no built-in
// password-hash default because all general-purpose hashes (SHA-2,
// SHA-3, BLAKE2) are too fast to safely store credentials with.
HashedUsers map[string]string
// HashedUsersFunc receives the stored hash string and the plaintext
// candidate; returns true on match. Required when HashedUsers is set.
// Callers typically wrap bcrypt.CompareHashAndPassword or
// argon2.IDKey + subtle.ConstantTimeCompare.
//
// 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
// SuccessHandler is called after successful credential validation,
// before c.Next(). Use for logging, metrics, or enriching the context.
// Matches the hook exposed by middleware/jwt and middleware/keyauth so
// mixed auth stacks can enrich uniformly.
SuccessHandler func(c *celeris.Context)
}
Config defines the basic auth middleware configuration.