basicauth

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

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

View Source
const UsernameKey = "basicauth_username"

UsernameKey is the context store key for the authenticated username.

Variables

View Source
var ErrUnauthorized = celeris.ErrUnauthorized

ErrUnauthorized is returned when authentication fails. ErrUnauthorized aliases celeris.ErrUnauthorized so cross-package errors.Is checks work.

Functions

func HashPassword

func HashPassword(password string) string

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",
		},
	})
}
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"
		},
	})
}
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"),
		},
	})
}
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"
		},
	})
}

func UsernameFromContext

func UsernameFromContext(c *celeris.Context) string

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.

Jump to

Keyboard shortcuts

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