Basic and Digest HTTP Authentication for golang http

Overview

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.

Legal

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.

Comments
  • generate md5 and sha1 formatting password from plaintext

    generate md5 and sha1 formatting password from plaintext

    When i beginning read the source code of go-http-auth, I spent a long time to find out how the password :$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1 of "hello" was generated in example/basic.go . I can't find any explain in document and any demo code.
    So, I implemented the function of generate md5 and sha1 formatting password from plaintext. And i believe these two functions is useful when writing the function func Secret(user, realm string) string, especially the raw password may be changed.

    opened by kenshinx 9
  • htpasswd utility support

    htpasswd utility support

    I've created htpasswd files using the htpasswd utility and, while go-http-auth supports the file format, the hashed passwords aren't matching up.

    This isn't my area of expertise, but I suspect go-http-auth is using a different salt than htpasswd and perhaps there are some other minor differences in how the MD5 and SHA algorithms are used between htpasswd and go-http-auth. Or I am I missing something?

    If htpasswd encrypted passwords aren't going to be supported by go-http-auth, how about a similar utility that will create an httpasswd file that will work with go-http-auth.

    Very happy with the package, by the way.

    Thanks.

    opened by vsheffer 7
  • Fixed concurrent map read and map write in default secret providers (issue crashes web server)

    Fixed concurrent map read and map write in default secret providers (issue crashes web server)

    Getting the following stacktrace when replacing htpasswd file during server run:

    fatal error: concurrent map read and map write
    
    goroutine 6472875 [running]:
    runtime.throw(0x6d07a9, 0x21)
    	/usr/lib/go-1.7/src/runtime/panic.go:566 +0x95 fp=0xc420501ad0 sp=0xc420501ab0
    runtime.mapaccess2_faststr(0x67a560, 0xc4200a7980, 0xc4202e3040, 0x9, 0xc4202e3080, 0x2)
    	/usr/lib/go-1.7/src/runtime/hashmap_fast.go:306 +0x52b fp=0xc420501b30 sp=0xc420501ad0
    github.com/abbot/go-http-auth.HtpasswdFileProvider.func2(0xc4202e3040, 0x9, 0x6cbc3b, 0x14, 0x2, 0xc4202e3080)
    	/root/vania-pooh/go/src/github.com/abbot/go-http-auth/users.go:132 +0x67 fp=0xc420501b78 sp=0xc420501b30
    github.com/abbot/go-http-auth.(*BasicAuth).CheckAuth(0xc4203d3cc0, 0xc42010e1e0, 0xc4203deb70, 0xc4202a6030)
    	/root/vania-pooh/go/src/github.com/abbot/go-http-auth/basic.go:83 +0x1ee fp=0xc420501c30 sp=0xc420501b78
    github.com/abbot/go-http-auth.(*BasicAuth).Wrap.func1(0x7eaf00, 0xc4204e8b60, 0xc42010e1e0)
    	/root/vania-pooh/go/src/github.com/abbot/go-http-auth/basic.go:142 +0x46 fp=0xc420501c88 sp=0xc420501c30
    net/http.HandlerFunc.ServeHTTP(0xc4203d3d60, 0x7eaf00, 0xc4204e8b60, 0xc42010e1e0)
    	/usr/lib/go-1.7/src/net/http/server.go:1726 +0x44 fp=0xc420501cb0 sp=0xc420501c88
    net/http.(*ServeMux).ServeHTTP(0xc42029a0c0, 0x7eaf00, 0xc4204e8b60, 0xc42010e1e0)
    	/usr/lib/go-1.7/src/net/http/server.go:2022 +0x7f fp=0xc420501cf0 sp=0xc420501cb0
    net/http.serverHandler.ServeHTTP(0xc42005e880, 0x7eaf00, 0xc4204e8b60, 0xc42010e1e0)
    	/usr/lib/go-1.7/src/net/http/server.go:2202 +0x7d fp=0xc420501d38 sp=0xc420501cf0
    net/http.(*conn).serve(0xc4200f5880, 0x7eb440, 0xc420184c00)
    	/usr/lib/go-1.7/src/net/http/server.go:1579 +0x4b7 fp=0xc420501f98 sp=0xc420501d38
    runtime.goexit()
    	/usr/lib/go-1.7/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc420501fa0 sp=0xc420501f98
    created by net/http.(*Server).Serve
    	/usr/lib/go-1.7/src/net/http/server.go:2293 +0x44d
    

    Added RWLock where necessary.

    opened by vania-pooh 6
  • security concerns

    security concerns

    You should not use constant time comparisons (due to possible timing attacks), and is the hashing done using md5 by default? See https://github.com/goji/httpauth for how it does this.

    opened by 0xdabbad00 5
  • Authenticated Request

    Authenticated Request

    Hi there,

    I'm running into a problem because using the library essentially changes the signature of the handle func and requires AuthenticatedRequest everywhere. This makes all subsequent method calls to methods that require http.Request fail.

    opened by ralfr 5
  • How to dynamically enable/disable authentication?

    How to dynamically enable/disable authentication?

    The situation is following:

    • config.yaml is structured in the following way:
    auth:
      - /path1:
          - username1: <username>
            password1: <password>
          - username2: <username>
            password2: <password>
      - /path2:
          - username: <username>
            password: <password>
    

    Now during the app initialization, I would like to enable Basic authentication for the path if respective path record is present and disable it otherwise (i.e. let all incoming request pass). I didn't manage to do that in any way, because auth expects auth.AuthenticatedHandlerFunc while http expects http.HandlerFunc and they are not interchangeable. That means that you need 2 handler functions - one for normal http, the other for Basic auth. That is kinda cumbersome.

    So I just wanted to ask if I didn't oversee something. Am I right that it cannot be done easily as the interface is design right now?

    Perhaps there could be another version of auth.Wrap that would simply put an empty Username into the AuthenticatedRequest passed into the handler and would not even attempt to authenticate the request?

    Let me know what you think about it, I could even write it myself and send a pull request!

    opened by tchap 5
  • intermittent failure to find passwords (possible race?)

    intermittent failure to find passwords (possible race?)

    I'm finding this works great on most of my sites, and has been a drop-in replacement for Apache, but I have some exceptions. On a page that embeds two iframes that hit my protected (ie hits the server to check passwords in parallel twice at nearly the same moment), even if I have the password cached already, it fails to find a password, and gets int a loop where no matter how many times I enter it, it fails.

    Curious if there is a race condition behind this. I'm attempting to debug.

    opened by sakoht 4
  • README Example could use improvement

    README Example could use improvement

    Hi, This library is something I want to use, but there are no examples for how to use it. Specifically, your README does not show how to implement a Secret() func.. the comment says that the password is "hello", but it returns some hash. How should I generate that hash?
    Thanks, Rob

    opened by robfig 4
  • MD5Crypt takes up high CPU

    MD5Crypt takes up high CPU

    [Scene] hi all

    we use the go-http-auth for request authrization, but it takes up high CPU usage, the CPU graph as follows: image

    [Code analysis] According to the code, we see there is 1000 times loop for computing "final", we want to know if the operation is in line with expectations.

    The questions are as follows:

    1. Can we delete the loop ?
    2. If you want to save the mechanism, Whether to consider the parameters(1000 times loop) can be configured? image

    Thanks a lot !

    opened by Tovi163 3
  • DigestAuth functions aren't thread-safe (Race conditions)

    DigestAuth functions aren't thread-safe (Race conditions)

    go build -race, will add instrumentation to catch race conditions. It caught problem within DigestAuth.clients (map)

    I'm attaching a copy of digest.go. I changed the mutex to be a read/write mutex, so you could have finer grain control over it. this copy doesn't cause problems with -race

    Also I started to fix golint problems https://github.com/golang/lint. But stopped, because it was getting out of hand. (Sorry for dirtying up the answer) digest.txt

    Thanks for your awesome work on the repo!!

    digest.txt is really digest.go!

    opened by nlacey 3
  • Fixed detection of bcrypt prefixes

    Fixed detection of bcrypt prefixes

    The original code only detected the prefix "$2y$", but "$2a$" and "$2b$" are also valid. See https://en.wikipedia.org/wiki/Bcrypt.

    opened by JMelbyClypd 3
  • Imlement http.Handler interface

    Imlement http.Handler interface

    It good that we may set basic auth on per-endpoint level

    http.HandleFunc("/user/", authenticator.Wrap(handleUser))
    http.HandleFunc("/book/", authenticator.Wrap(handleBook))
    

    But for most cases it would be better to have some global "interceptor" for all endpoints. And looks like the most simple way is to make a delegating Handler and use it with SericeMux. Here I created a basic sample: https://gist.github.com/stokito/24b3e6efb3e1e9357c7d964a7df2c18c

    Can you add such AuthHandler into the library?

    opened by stokito 0
  • More crypters [Patch included]

    More crypters [Patch included]

    Hi,

    thanks for your great work, it's very usefull for me.

    I did a little change to add support for more crypters:

    https://github.com/webmeisterei/go-http-auth/commit/7616ea56faee4a7f203c195f22bee42c08774ce4

    Do you want a pull request for that?

    Thanks and Kind regards, René

    opened by jochumdev 2
  • Modify cache purging limit

    Modify cache purging limit

    When the authenticator's cache is purged, there was a consistent slice bounds out of range [:200] with capacity 181 panic occurring. Purging the entire cache resolves this error.

    This is moved over from https://github.com/abbot/go-http-auth/pull/68, which is closed.

    opened by athum 1
  • Documentation on how to set passwords.

    Documentation on how to set passwords.

    This library is great, and seems to be a full replacement for the standard Apache http auth. However it is impossible to actually use if someone doesn't know how to set passwords. I think people are left doing what I am doing: scratching my head and reading the source code, guessing, and failing repeatedly.

    Ultimately this needs a simple extension to the README that:

    • enumerates the ways that a password can be set
    • shows one example of using each

    Ideally one example shows how to just make it read a standard .htaccess file and have it just work. Everything else is a corner case.

    If I figure this out, I'll make a PR.

    opened by sakoht 1
Owner
Lev Shamardin
Lev Shamardin
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Paul Greenberg 697 Jan 8, 2023
Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Dinesh Bhattarai 0 Aug 5, 2022
X3 - A template for using HTTP Basic Authentication in Go

HTTP Basic Auth in Go This is a template for using HTTP Basic Auth in a Go appli

Joel Dare 92 Sep 28, 2022
Authelia: an open-source authentication and authorization server providing two-factor authentication

Authelia is an open-source authentication and authorization server providing two

Streato 0 Jan 5, 2022
A simple passwordless authentication middleware that uses only email as the authentication provider

email auth A simple passwordless authentication middleware that uses only email as the authentication provider. Motivation I wanted to restrict access

Miroslav Šedivý 5 Jul 27, 2022
Goauth - Basic username password cookie based authentication with Go Lang

goauth [WIP] Basic username password cookie based authentication with Go Lang Overview Use a Postgres DB to store Sign-in and Sign-up info Redis for c

Joseph Chen 0 Jan 4, 2022
HTTP-server-with-auth# HTTP Server With Authentication

HTTP-server-with-auth# HTTP Server With Authentication Introduction You are to use gin framework package and concurrency in golang and jwt-go to imple

Saba Sahban 12 Nov 9, 2022
Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.

❗ Cache package has been moved to libcache repository Go-Guardian Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to

Sanad Haj Yahya 426 Dec 23, 2022
HTTP Authentication middlewares

goji/httpauth httpauth currently provides HTTP Basic Authentication middleware for Go. It is compatible with Go's own net/http, goji, Gin & anything t

Goji 217 Dec 23, 2022
Go (lang) HTTP session authentication

Go Session Authentication See git tags/releases for information about potentially breaking change. This package uses the Gorilla web toolkit's session

Cameron Little 218 Dec 22, 2022
Example of a simple application which is powered by a third-party oAuth 2.0 server for it's authentication / authorization. Written in Golang.

go mod init github.com/bartmika/osin-thirdparty-example go get github.com/spf13/cobra go get github.com/openshift/osin go get github.com/openshift/osi

Bartlomiej Mika 0 Jan 4, 2022
A simple authentication web application in Golang (using jwt)

Simple Authentication WebApp A simple authentication web app in Go (using JWT) Routes Path Method Data /api/v1/auth/register POST {"firstname":,"lastn

Shayan 2 Feb 6, 2022
Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applications.

Goth: Multi-Provider Authentication for Go Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applic

Mark Bates 4k Dec 29, 2022
[DEPRECATED] Go package authcookie implements creation and verification of signed authentication cookies.

Package authcookie import "github.com/dchest/authcookie" Package authcookie implements creation and verification of signed authentication cookies. Co

Dmitry Chestnykh 111 Dec 22, 2022
Herbert Fischer 198 Oct 8, 2022
Simple authentication and books management with GoFiber

Simple authentication and books management with GoFiber Simple authentication system with gofiber. Endpoints GET /api - Welcome message POST /api/auth

Arif Amir 14 Nov 27, 2022
A collection of authentication Go packages related to OIDC, JWKs and Distributed Claims.

cap (collection of authentication packages) provides a collection of related packages which enable support for OIDC, JWT Verification and Distributed Claims.

HashiCorp 341 Dec 7, 2022
An imaginary authentication and session tracking service that is defined in this Apiary

Userland This repository contains impelementation of "Userland" on boarding project Userland is an imaginary authentication and session tracking servi

Raja Moris 0 Dec 5, 2021
A demo of authentication and authorization using jwt

Nogopy Hi, this a demo of how to use jwt for authentication in microservices Keep in mind that this is a demo of how to authenticate using jwt, we don

null 2 Nov 1, 2021