auth

package module
v0.0.0-...-89447eb Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2024 License: Apache-2.0 Imports: 19 Imported by: 0

README

HTTP Authentication implementation in Go

This is an implementation of HTTP Basic and HTTP Digest authentication in Go language. It is designed as a simple wrapper for http.RequestHandler functions.

Features

  • Supports HTTP Basic and HTTP Digest authentication.
  • Supports htpasswd and htdigest formatted files.
  • Automatic reloading of password files.
  • Pluggable interface for user/password storage.
  • Supports MD5, SHA1 and BCrypt for Basic authentication password storage.
  • Configurable Digest nonce cache size with expiration.
  • Wrapper for legacy http handlers (http.HandlerFunc interface)

Example usage

This is a complete working example for Basic auth:

package main

import (
        "fmt"
        "net/http"

        auth "github.com/abbot/go-http-auth"
)

func Secret(user, realm string) string {
        if user == "john" {
                // password is "hello"
                return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
        }
        return ""
}

func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
        fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
}

func main() {
        authenticator := auth.NewBasicAuthenticator("example.com", Secret)
        http.HandleFunc("/", authenticator.Wrap(handle))
        http.ListenAndServe(":8080", nil)
}

See more examples in the "examples" directory.

This module is developed under Apache 2.0 license, and can be used for open and proprietary projects.

Copyright 2012-2013 Lev Shamardin

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file or any other part of this project except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Documentation

Overview

Package auth is an implementation of HTTP Basic and HTTP Digest authentication.

Index

Constants

View Source
const AuthUsernameHeader = "X-Authenticated-Username"

AuthUsernameHeader is the header set by JustCheck functions. It contains an authenticated username (if authentication was successful).

View Source
const DefaultClientCacheSize = 1000

Default values for ClientCacheSize and ClientCacheTolerance for DigestAuth

View Source
const DefaultClientCacheTolerance = 100

Variables

View Source
var (
	// NormalHeaders are the regular Headers used by an HTTP Server for
	// request authentication.
	NormalHeaders = &Headers{
		Authenticate:      "WWW-Authenticate",
		Authorization:     "Authorization",
		AuthInfo:          "Authentication-Info",
		UnauthCode:        http.StatusUnauthorized,
		UnauthContentType: "text/plain",
		UnauthResponse:    fmt.Sprintf("%d %s\n", http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized)),
	}

	// ProxyHeaders are Headers used by an HTTP Proxy server for proxy
	// access authentication.
	ProxyHeaders = &Headers{
		Authenticate:      "Proxy-Authenticate",
		Authorization:     "Proxy-Authorization",
		AuthInfo:          "Proxy-Authentication-Info",
		UnauthCode:        http.StatusProxyAuthRequired,
		UnauthContentType: "text/plain",
		UnauthResponse:    fmt.Sprintf("%d %s\n", http.StatusProxyAuthRequired, http.StatusText(http.StatusProxyAuthRequired)),
	}
)

Functions

func DigestAuthParams

func DigestAuthParams(authorization string) map[string]string

Parse Authorization header from the http.Request. Returns a map of auth parameters or nil if the header is not a valid parsable Digest auth header.

func H

func H(data string) string

H function for MD5 algorithm (returns a lower-case hex MD5 digest)

func JustCheck

func JustCheck(auth AuthenticatorInterface, wrapped http.HandlerFunc) http.HandlerFunc

func MD5Crypt

func MD5Crypt(password, salt, magic []byte) []byte

MD5 password crypt implementation

func ParseList

func ParseList(value string) []string

ParseList parses a comma-separated list of values as described by RFC 2068 and returns list elements.

Lifted from https://code.google.com/p/gorilla/source/browse/http/parser/parser.go which was ported from urllib2.parse_http_list, from the Python standard library.

func ParsePairs

func ParsePairs(value string) map[string]string

ParsePairs extracts key/value pairs from a comma-separated list of values as described by RFC 2068 and returns a map[key]value. The resulting values are unquoted. If a list element doesn't contain a "=", the key is the element itself and the value is an empty string.

Lifted from https://code.google.com/p/gorilla/source/browse/http/parser/parser.go

func RandomKey

func RandomKey() string

RandomKey returns a random 16-byte base64 alphabet string

Types

type AuthenticatedHandlerFunc

type AuthenticatedHandlerFunc func(http.ResponseWriter, *AuthenticatedRequest)

AuthenticatedHandlerFunc is like http.HandlerFunc, but takes AuthenticatedRequest instead of http.Request

type AuthenticatedRequest

type AuthenticatedRequest struct {
	http.Request
	/*
	 Authenticated user name. Current API implies that Username is
	 never empty, which means that authentication is always done
	 before calling the request handler.
	*/
	Username string
}

Request handlers must take AuthenticatedRequest instead of http.Request

type Authenticator

type Authenticator func(AuthenticatedHandlerFunc) http.HandlerFunc

Authenticator wraps an AuthenticatedHandlerFunc with authentication-checking code.

Typical Authenticator usage is something like:

authenticator := SomeAuthenticator(...)
http.HandleFunc("/", authenticator(my_handler))

Authenticator wrapper checks the user authentication and calls the wrapped function only after authentication has succeeded. Otherwise, it returns a handler which initiates the authentication procedure.

type AuthenticatorInterface

type AuthenticatorInterface interface {
	// NewContext returns a new context carrying authentication
	// information extracted from the request.
	NewContext(ctx context.Context, r *http.Request) context.Context

	// Wrap returns an http.HandlerFunc which wraps
	// AuthenticatedHandlerFunc with this authenticator's
	// authentication checks.
	Wrap(AuthenticatedHandlerFunc) http.HandlerFunc
}

type BasicAuth

type BasicAuth struct {
	Realm   string
	Secrets SecretProvider
	// Headers used by authenticator. Set to ProxyHeaders to use with
	// proxy server. When nil, NormalHeaders are used.
	Headers *Headers
}

func NewBasicAuthenticator

func NewBasicAuthenticator(realm string, secrets SecretProvider) *BasicAuth

func (*BasicAuth) CheckAuth

func (a *BasicAuth) CheckAuth(r *http.Request) string

Checks the username/password combination from the request. Returns either an empty string (authentication failed) or the name of the authenticated user.

Supports MD5 and SHA1 password entries

func (*BasicAuth) NewContext

func (a *BasicAuth) NewContext(ctx context.Context, r *http.Request) context.Context

NewContext returns a context carrying authentication information for the request.

func (*BasicAuth) RequireAuth

func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request)

http.Handler for BasicAuth which initiates the authentication process (or requires reauthentication).

func (*BasicAuth) Wrap

BasicAuthenticator returns a function, which wraps an AuthenticatedHandlerFunc converting it to http.HandlerFunc. This wrapper function checks the authentication and either sends back required authentication headers, or calls the wrapped function with authenticated username in the AuthenticatedRequest.

type DigestAuth

type DigestAuth struct {
	Realm            string
	Opaque           string
	Secrets          SecretProvider
	PlainTextSecrets bool
	IgnoreNonceCount bool
	// Headers used by authenticator. Set to ProxyHeaders to use with
	// proxy server. When nil, NormalHeaders are used.
	Headers *Headers

	/*
	   Approximate size of Client's Cache. When actual number of
	   tracked client nonces exceeds
	   ClientCacheSize+ClientCacheTolerance, ClientCacheTolerance*2
	   older entries are purged.
	*/
	ClientCacheSize      int
	ClientCacheTolerance int
	// contains filtered or unexported fields
}

func NewDigestAuthenticator

func NewDigestAuthenticator(realm string, secrets SecretProvider) *DigestAuth

func (*DigestAuth) CheckAuth

func (da *DigestAuth) CheckAuth(r *http.Request) (username string, authinfo *string)

Check if request contains valid authentication data. Returns a pair of username, authinfo where username is the name of the authenticated user or an empty string and authinfo is the contents for the optional Authentication-Info response header.

func (*DigestAuth) JustCheck

func (a *DigestAuth) JustCheck(wrapped http.HandlerFunc) http.HandlerFunc

JustCheck returns function which converts an http.HandlerFunc into a http.HandlerFunc which requires authentication. Username is passed as an extra X-Authenticated-Username header.

func (*DigestAuth) NewContext

func (a *DigestAuth) NewContext(ctx context.Context, r *http.Request) context.Context

NewContext returns a context carrying authentication information for the request.

func (*DigestAuth) Purge

func (a *DigestAuth) Purge(count int)

Remove count oldest entries from DigestAuth.clients

func (*DigestAuth) RequireAuth

func (a *DigestAuth) RequireAuth(w http.ResponseWriter, r *http.Request)

http.Handler for DigestAuth which initiates the authentication process (or requires reauthentication).

func (*DigestAuth) Wrap

Wrap returns an Authenticator which uses HTTP Digest authentication. Arguments:

realm: The authentication realm.

secrets: SecretProvider which must return HA1 digests for the same realm as above.

type File

type File struct {
	Path string
	Info os.FileInfo
	/* must be set in inherited types during initialization */
	Reload func()
	// contains filtered or unexported fields
}

Common functions for file auto-reloading

func (*File) ReloadIfNeeded

func (f *File) ReloadIfNeeded()

type Headers

type Headers struct {
	Authenticate      string // WWW-Authenticate
	Authorization     string // Authorization
	AuthInfo          string // Authentication-Info
	UnauthCode        int    // 401
	UnauthContentType string // text/plain
	UnauthResponse    string // Unauthorized.
}

Headers contains header and error codes used by authenticator.

func (*Headers) V

func (h *Headers) V() *Headers

V returns NormalHeaders when h is nil, or h otherwise. Allows to use uninitialized *Headers values in structs.

type HtdigestFile

type HtdigestFile struct {
	File
	Users map[string]map[string]string
	// contains filtered or unexported fields
}

Structure used for htdigest file authentication. Users map realms to maps of users to their HA1 digests.

type HtpasswdFile

type HtpasswdFile struct {
	File
	Users map[string]string
	// contains filtered or unexported fields
}

Structure used for htdigest file authentication. Users map users to their salted encrypted password

type Info

type Info struct {
	// Authenticated is set to true when request was authenticated
	// successfully, i.e. username and password passed in request did
	// pass the check.
	Authenticated bool

	// Username contains a user name passed in the request when
	// Authenticated is true. It's value is undefined if Authenticated
	// is false.
	Username string

	// ResponseHeaders contains extra headers that must be set by server
	// when sending back HTTP response.
	ResponseHeaders http.Header
}

Info contains authentication information for the request.

func FromContext

func FromContext(ctx context.Context) *Info

FromContext returns authentication information from the context or nil if no such information present.

func (*Info) UpdateHeaders

func (i *Info) UpdateHeaders(headers http.Header)

UpdateHeaders updates headers with this Info's ResponseHeaders. It is safe to call this function on nil Info.

type MD5Entry

type MD5Entry struct {
	Magic, Salt, Hash []byte
}

func NewMD5Entry

func NewMD5Entry(e string) *MD5Entry

type SecretProvider

type SecretProvider func(user, realm string) string

SecretProvider is used by authenticators. Takes user name and realm as an argument, returns secret required for authentication (HA1 for digest authentication, properly encrypted password for basic).

Returning an empty string means failing the authentication.

func HtdigestFileProvider

func HtdigestFileProvider(filename string) SecretProvider

SecretProvider implementation based on htdigest-formated files. Will reload htdigest file on changes. Will panic on syntax errors in htdigest files.

func HtpasswdFileProvider

func HtpasswdFileProvider(filename string) SecretProvider

SecretProvider implementation based on htpasswd-formated files. Will reload htpasswd file on changes. Will panic on syntax errors in htpasswd files. Realm argument of the SecretProvider is ignored.

Jump to

Keyboard shortcuts

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