Skip to content

Commit 51fee2c

Browse files
committed
Initital commit
0 parents  commit 51fee2c

9 files changed

Lines changed: 177 additions & 0 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# HTTP Basic Auth in Go
2+
3+
This is a template for using HTTP Basic Auth in a Go web interface.

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module joeldare/x3
2+
3+
go 1.16

localhost.crt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDFjCCAf4CCQDWuqU8QfUUhzANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJV
3+
UzENMAsGA1UECAwEVXRhaDEPMA0GA1UEBwwGSG9vcGVyMR4wHAYDVQQKDBVEZXNl
4+
cmV0IERpZ2l0YWwgTWVkaWEwHhcNMjExMjI5MTcyNzAzWhcNMjIxMjI5MTcyNzAz
5+
WjBNMQswCQYDVQQGEwJVUzENMAsGA1UECAwEVXRhaDEPMA0GA1UEBwwGSG9vcGVy
6+
MR4wHAYDVQQKDBVEZXNlcmV0IERpZ2l0YWwgTWVkaWEwggEiMA0GCSqGSIb3DQEB
7+
AQUAA4IBDwAwggEKAoIBAQDLGBREldvWtsaHsXvJbMSay9rVWrgQq+pOI6SPKOZq
8+
tKbHRU8+ICK5XRngODyA3NfMLaSTVlV936eFuQFKZcdSWSjm4HxvzRJqp4Q2+U/a
9+
KgW2bwkXu2rS4lDhvHHhD+gykvugQ/+8PAueCstOyhvj6Cre0B73q3Y1Kk6PqwA9
10+
CPCy+4yWae2ocOU2KSi9lTtRdhzoqngc5L/qxLSpbXKFfZM2r2IbsTftMjXC+1um
11+
5AGesnrkws/J2CRAC5oaKqdRK751ycseLoSPO+Q+n/ECMFoHfr40D6BFS+CxqQCj
12+
x5cvKypw647njfWkioWH8YGeU/LjbnvXzE1sXWM8G6hfAgMBAAEwDQYJKoZIhvcN
13+
AQEFBQADggEBAAWLRXgSZNsZug/B6+CBxY4pmemrQrTVWDV+sjIcMrwxOBrPbR5T
14+
h89ZBF3vBUTLKPDLBouVioDqApOGIVYbyabvUN8fnkdKWf34YmwksHSDlKKeheYD
15+
EgBWIpKsK0/KxkEkZ0IBf9Htl+fbPaWPFNbzxPNUQuu1WxF4Civu5eF5ADqmFUVM
16+
DehuIPCz3aiX3pWs9b5Jra8sdyxEgKKPNEuiRyt79Mzh6irP6vNe/8HxVJYEuXUi
17+
0sF3ssscQXSxH1iQ9XEjhPgOkN15aRZReErBNwgikgSyQmmUd2e4UcO1sJOgYrMi
18+
RZEHeOVgHq4uI+fQjK/tO33b1cwxVaG8bAk=
19+
-----END CERTIFICATE-----

localhost.csr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIICkjCCAXoCAQAwTTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
3+
BAcMBkhvb3BlcjEeMBwGA1UECgwVRGVzZXJldCBEaWdpdGFsIE1lZGlhMIIBIjAN
4+
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyxgURJXb1rbGh7F7yWzEmsva1Vq4
5+
EKvqTiOkjyjmarSmx0VPPiAiuV0Z4Dg8gNzXzC2kk1ZVfd+nhbkBSmXHUlko5uB8
6+
b80SaqeENvlP2ioFtm8JF7tq0uJQ4bxx4Q/oMpL7oEP/vDwLngrLTsob4+gq3tAe
7+
96t2NSpOj6sAPQjwsvuMlmntqHDlNikovZU7UXYc6Kp4HOS/6sS0qW1yhX2TNq9i
8+
G7E37TI1wvtbpuQBnrJ65MLPydgkQAuaGiqnUSu+dcnLHi6EjzvkPp/xAjBaB36+
9+
NA+gRUvgsakAo8eXLysqcOuO5431pIqFh/GBnlPy425718xNbF1jPBuoXwIDAQAB
10+
oAAwDQYJKoZIhvcNAQELBQADggEBAKYVzfoJ7FuQJYLiPyPGT0UnAD7BUCWdyBCh
11+
cnvdKqkJ8vW9p2CE9A+v4MQmZPCYi5twfzp+rc4wiwe0X8oHOWVOXxHwwz/+4vZd
12+
YqpGwwTuaUAn6gY0Mz2LiHRyDY+JBh8yYHZqsG1+S09WM8ERG966R5e9mAQbqvqb
13+
1W+d7XoKDlXghC8ocf6Lg7c+vWbsABUeWtPLNcvDDY9+3GMZ6gqsiBuSQMgcHJVZ
14+
vV/8AmsrlwSmruzMDGD6Lu5bBmRIqUMTMQ8gGB6i2LzIkDVPKSPEMyPafcatr4Cu
15+
Sv0Bb6RzUBxXHdMADQ8Tg30Z0P2VNeEHkyZ+ZZQ4Rj6ScP5MtFU=
16+
-----END CERTIFICATE REQUEST-----

localhost.key

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLGBREldvWtsaH
3+
sXvJbMSay9rVWrgQq+pOI6SPKOZqtKbHRU8+ICK5XRngODyA3NfMLaSTVlV936eF
4+
uQFKZcdSWSjm4HxvzRJqp4Q2+U/aKgW2bwkXu2rS4lDhvHHhD+gykvugQ/+8PAue
5+
CstOyhvj6Cre0B73q3Y1Kk6PqwA9CPCy+4yWae2ocOU2KSi9lTtRdhzoqngc5L/q
6+
xLSpbXKFfZM2r2IbsTftMjXC+1um5AGesnrkws/J2CRAC5oaKqdRK751ycseLoSP
7+
O+Q+n/ECMFoHfr40D6BFS+CxqQCjx5cvKypw647njfWkioWH8YGeU/LjbnvXzE1s
8+
XWM8G6hfAgMBAAECggEBAKEU/B5Z7f+jAFvnvZLJHjbYsTy/s3YlpLVNN9wESJ0h
9+
o5YxtuRDgMccvMVGVVav0sky+nGR7ETl+2zoi8mCaFE8PmDAdHIIaS8Gpqsjmt4i
10+
rl1APCoCkHuq3RPt7zTe9QAH7GP1CwU1atFzJkXbr7tYDYij8avm5t7MK3tv2cSN
11+
xJzZJYBM3GxRPmKKWLdg3Ghz2Fqvd4GP6/5JOtLQcycpIXRFI0wFEFAsvIQnrdca
12+
l8hlZdAPvYODKDayPaMMrC70OK1T7MfaPIXH4ZVvIcpy1iw+ESWNZ4Eecgk0MLeS
13+
xmCRq0KZHj0nHUZFHOJPuCuct96fkzdlSo5rzTBVGiECgYEA7zGL/7B056v3g/mS
14+
73d0CsNjjvkI0cOSMa3m+7u0rhTjNwXvZTyiTAfjEQCMOjPOkHifD7iNYFv5H7VG
15+
EfM2F8cZo3jTZ92r07w6XM6qptCtMnntXSHubIt4syb1FB1tzTjJ1AvjJVhvIuat
16+
2vhbZVmsD5Y4YAm/ky2OeNQdzAsCgYEA2V0y8STT2GAMgUUN3WKboCDvEis+glon
17+
FwrmszcllG7jPyVZxGffSRb8sjhRN2a1yOqsxXhDKIhxaK/p21ajKiBM0BnrFttg
18+
SvnLBckx8xepuUwanxaCnN8WZeen1qOvtdALRP+Tm4vS6Fh5gE62MHa/jM165DyQ
19+
RhOYRSSqdX0CgYEAi3Xk/ZChqM4QQ4eJT0vjgb8IVj0HEl6n54VQbqezoegVzmgM
20+
e4dNzWyvzKL4H5tDLeLWQvFEpNEbQIyNrTuT52sznKd/A0kwvQQ7Nw9cWmTDBvIm
21+
Hi4BeJIdLr9hF3hNI+Gfc532sziLm9rJtSknCMGu22untP8aDrL6JaLvOJ8CgYBX
22+
ogGFwyk9lQu1mleKp9TCbES2eITNHPehjJ2SJ2uZOlOYA8D7ND2LRB9A4v+rbFdh
23+
12ssed3pm4jNgg6whW9m7nrJc4maP3vE/oxhmsnujd25fPtGpFaoVDC9iPXbzUZr
24+
8KJ6gOfL0EWJsxHZLuK5C0cSx00Cc4BfIEtFpRCsKQKBgQDUfIY4PW7miGS5t+AI
25+
McQQGe8rqLnfbpck1PRMX0NK09S9LjwytxePW4+NwtHrowWpfSYa43+bPlVruD/H
26+
KZFN9n84pHuctOBgukuC7O/qKenksUmFFrsxrvsjgO0IFzyrySTbl3e6DXrF7ouc
27+
nnqN9mgLAmonZhED3OkMZqCybA==
28+
-----END PRIVATE KEY-----

www/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>This is served from the <em>./www</em> directory.</p>

www/test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a test file.

x3

6.25 MB
Binary file not shown.

x3.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package main
2+
3+
import (
4+
"crypto/sha256"
5+
"encoding/base64"
6+
"fmt"
7+
"io"
8+
"math/rand"
9+
"net/http"
10+
"net/url"
11+
"time"
12+
)
13+
14+
type application struct {
15+
config struct {
16+
port string
17+
path string
18+
cert string
19+
key string
20+
}
21+
user struct {
22+
name string
23+
pass string
24+
}
25+
}
26+
27+
func main() {
28+
// Instantiate app with some application data
29+
app := new(application)
30+
// Setup the config data
31+
app.config.port = "8003"
32+
app.config.path = "./www"
33+
app.config.cert = "localhost.crt"
34+
app.config.key = "localhost.key"
35+
// Setup the user data
36+
app.user.name = "admin"
37+
app.user.pass = "A6xnQhbz4Vx2HuGl4lXwZ5U2I8iziLRFnhP5eNfIRvQ=" // 1234
38+
// Setup some routes
39+
http.HandleFunc("/", app.fileHandler)
40+
http.HandleFunc("/hello", app.helloHandler)
41+
http.HandleFunc("/hash", app.hashHandler)
42+
// Start a server
43+
fmt.Printf("Server started on port %s\n", app.config.port)
44+
if err := http.ListenAndServeTLS(":"+app.config.port, app.config.cert, app.config.key, nil); err != nil {
45+
fmt.Println(err)
46+
}
47+
}
48+
49+
// A function that authenticates the user and returns true or false
50+
func (app *application) auth(w http.ResponseWriter, r *http.Request) bool {
51+
// Grab the username, password, and a verification that they were formatted ok in the request
52+
user, pass, ok := r.BasicAuth()
53+
// If the header includes credentials
54+
if ok {
55+
// Base64 encode the recieved password
56+
sum := sha256.Sum256([]byte(pass))
57+
encodedPass := base64.StdEncoding.EncodeToString(sum[:])
58+
// If the passed credentials are correct
59+
if user == app.user.name && encodedPass == app.user.pass {
60+
return true
61+
}
62+
}
63+
// Sleep for some random amount of time to prevent timed attacks
64+
rand.Seed(time.Now().UnixNano())
65+
wait := rand.Intn(2500)
66+
fmt.Printf("Waiting %d milliseconds\n", wait)
67+
time.Sleep(time.Duration(wait) * time.Millisecond)
68+
// Set a header reporting unauthorized and requesting credentials
69+
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
70+
http.Error(w, "Unauthorized", http.StatusUnauthorized)
71+
return false
72+
}
73+
74+
func (app *application) fileHandler(w http.ResponseWriter, r *http.Request) {
75+
// Authorize the user and return on failure
76+
if !app.auth(w, r) {
77+
return
78+
}
79+
// Parse the url for the path
80+
u, err := url.ParseRequestURI(r.RequestURI)
81+
if err != nil {
82+
fmt.Println("Unable to parse url.")
83+
}
84+
fmt.Println("Serving " + app.config.path + u.Path)
85+
// Serve a file from the default directory
86+
http.ServeFile(w, r, app.config.path+u.Path)
87+
}
88+
89+
// A handler that authorizes the user and says hello
90+
func (app *application) helloHandler(w http.ResponseWriter, r *http.Request) {
91+
// Authorize the user and return on failure
92+
if !app.auth(w, r) {
93+
return
94+
}
95+
// Say hello
96+
w.Header().Add("content-type", "text/html")
97+
io.WriteString(w, "Hello World.\n")
98+
}
99+
100+
// An example of how to hash a password and store it
101+
func (app *application) hashHandler(w http.ResponseWriter, r *http.Request) {
102+
pass := r.URL.Query().Get("pass")
103+
sum := sha256.Sum256([]byte(pass))
104+
w.Header().Add("content-type", "text/html")
105+
io.WriteString(w, base64.StdEncoding.EncodeToString(sum[:]))
106+
}

0 commit comments

Comments
 (0)