Golang : Basic authentication with .htpasswd file

 

Si vous cherchez à protéger une page web avec une authentification de base. Cela peut être fait facilement avec Golang. Dans ce tutoriel, nous allons d'abord explorer comment mettre en œuvre l'authentification de base avec nom d'utilisateur et mot de passe dans le code source. Ensuite, nous trouverons le nom d'utilisateur et le mot de passe dans le fichier .htpasswd.

Cet exemple de code demandera à l'utilisateur son nom d'utilisateur et son mot de passe avant de lui permettre d'accéder au site.

 

 package main

 

 import (

         "encoding/base64"

         "github.com/gorilla/mux"

         "net/http"

         "strings"

 )

 

 var username = []byte("hello")

 var password = []byte("password")

 

 func BasicAuth(w http.ResponseWriter, r *http.Request, user, pass []byte) bool {

         s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)

         if len(s) != 2 {

                 return false

         }

 

         b, err := base64.StdEncoding.DecodeString(s[1])

         if err != nil {

                 return false

         }

 

         pair := strings.SplitN(string(b), ":", 2)

         if len(pair) != 2 {

                 return false

         }

 

         return pair[0] == string(user) && pair[1] == string(pass)

 }

 

 func Home(w http.ResponseWriter, r *http.Request) {

         w.Write([]byte("Hello, World!"))

 }

 

 func Protected(w http.ResponseWriter, r *http.Request) {

 

         // pass from global variables

         if BasicAuth(w, r, username, password) {

                 w.Write([]byte("Welcome to the Protected Page!!"))

                 return

         }

 

         w.Header().Set("WWW-Authenticate", `Basic realm="Beware! Protected REALM! "`)

         w.WriteHeader(401)

         w.Write([]byte("401 Unauthorized\n"))

 }

 

 func main() {

         mx := mux.NewRouter()

         mx.HandleFunc("/", Home)

         mx.HandleFunc("/protectedpage/", Protected)

 

         http.ListenAndServe(":8080", mx)

 }

Exécutez ce code et dirigez votre navigateur vers http://localhost:8080/protectedpage/. Vous serez invité à entrer votre nom d'utilisateur et votre mot de passe, qui sont "hello" et "password".

Si vous recherchez une option plus sûre, vous pouvez choisir de charger le nom d'utilisateur et le mot de passe à partir du fichier .htpasswd.

Utilisez  http://www.htaccesstools.com/htpasswd-generator/  pour générer un fichier .htpasswd. Dans cet exemple, nous utiliserons username et  password

Assurez-vous que le fichier ne comporte qu'une seule ligne.

cat .htpasswd

username:$apr1$F9tXeu9r$oairgF8rFh2oRUC4Dl9v/1

Nous allons lire le fichier .htpasswd avec le paquet github.com/abbot/go-http-auth

Exécutez ce code et dirigez votre navigateur vers http://localhost:8080/protectedpage/. Vous serez invité à entrer votre nom d'utilisateur et votre mot de passe, qui sont hello et   password

 package main

 

 import (

         "fmt"

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

         "github.com/gorilla/mux"

         "net/http"

 )

 

 func Home(w http.ResponseWriter, r *http.Request) {

         w.Write([]byte("Hello, World!"))

 }

 

 func Protected(w http.ResponseWriter, r *auth.AuthenticatedRequest) {

         w.Write([]byte(fmt.Sprintf("Hello, %s!", r.Username)))

 }

 

 func main() {

 

         // read from .htpasswd file

         htpasswd := auth.HtpasswdFileProvider("./.htpasswd")

         authenticator := auth.NewBasicAuthenticator("Basic Realm", htpasswd)

 

         mx := mux.NewRouter()

         mx.HandleFunc("/", Home)

         mx.HandleFunc("/protectedpage/", authenticator.Wrap(Protected))

 

         http.ListenAndServe(":8080", mx)

 }

Le résultat devrait être le même que le code précédent, sauf que cette fois, le nom d'utilisateur et le mot de passe sont tirés d'un fichier au lieu d'être codés en dur dans le code source.

Références :

https://gist.github.com/jbuchbinder/5816604

https://github.com/abbot/go-http-auth

Golang : Comment mettre en œuvre l'authentification à deux facteurs ?