Go Pentester - HTTP Servers(3)
Building Middleware with Negroni
Reasons use middleware, including logging requests, authenticating and authorizing users, and mapping resources.
Idiomatic HTTP Middleware for Golang. https://github.com/urfave/negroni
Install the negroni package.
go get github.com/urfave/negroni
PS: How to solve the go get can not work in China. Following is the best solution so far. https://github.com/goproxy/goproxy.cn
$ go env -w GO111MODULE=on $ go env -w GOPROXY=https://goproxy.cn,direct
Negroni example
package main
import (
"github.com/gorilla/mux"
"github.com/urfave/negroni"
"net/http"
)
func main() {
r := mux.NewRouter()
n := negroni.Classic()
n.UseHandler(r)
http.ListenAndServe(":8000",n)
}
Build and execute this program.

Create trivial middleware that prints a message and passes execution to the next middleware in the chain:
package main
import (
"fmt"
"github.com/gorilla/mux"
"github.com/urfave/negroni"
"net/http"
)
type trivial struct {
}
func (t *trivial) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
fmt.Println("Executing trivial middleware")
next(w, r)
}
func main() {
r := mux.NewRouter()
n := negroni.Classic()
n.UseHandler(r)
n.Use(&trivial{})
http.ListenAndServe(":8000",n)
}
Build and test this new program.

Adding Authentication with Negroni
Use of context, which can easily pass variables between functions.
package main
import (
"context"
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/urfave/negroni"
)
type badAuth struct {
Username string
Password string
}
func (b *badAuth) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
username := r.URL.Query().Get("username")
password := r.URL.Query().Get("password")
if username != b.Username && password !=b.Password {
http.Error(w, "Unauthorized", 401)
return
}
ctx := context.WithValue(r.Context(), "username", username)
r = r.WithContext(ctx)
next(w, r)
}
func hello(w http.ResponseWriter, r * http.Request) {
username := r.Context().Value("username").(string)
fmt.Fprintf(w, "Hi %s\n", username)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/hello",hello).Methods("GET")
n := negroni.Classic()
n.Use(&badAuth{
Username: "admin",
Password: "password",
})
n.UseHandler(r)
http.ListenAndServe(":8000", n)
}
Build and excute this program. Then test it by sending a few requests to the server.
curl -i http://localhost:8000/hello curl -i 'http://localhost:8000/hello?username=admin&password=password'

Logs on the server-side.


浙公网安备 33010602011771号