A set of conditional access control wrappers for golang-based web application, written in httprouter or http.HandlerFunc.
- variety of handler wrappers implemented in
AuthWrapperhelps you to protect resources forhttp.HandlerFuncandhttprouter.Handle. - several authentication providers and session management mechanisms are available in
authandsessionpackage for both ofhttpandhttprouterpackage. - simple IP-based filtering powered by
jpillora/ipfilter. (thanks!) - AND or OR synthetic wrapper with
httpfilter/syntesispackage, which enables you to apply two or moreAuthWrapperfor single route. (AuthWrapperis also supported). - Additional header management and built-in CORS support with
headerpackage (now only supported forhttprouter)
//in synthesis package
type AuthWrapper func (http.HandlerFunc, _ ...string) http.HandlerFunc
//in synthesis/rt_synthesis package
type AuthWrapper func (httprouter.Handle, _ ...string) httprouter.HandleAuthWrapper is the function type which receives http.HandlerFunc for its first argument, and returns http.HandlerFunc.
Its counter part for httprouter, AuthWrapper in rt_synthesis package is the function type which receives httprouter.Handle for its first argument, and returns http.HandlerFunc.
Both of them can receive additional string parameter for internal conditional evaluation, but they are not essential in every AuthWrapper implementation.
If you feel http.HandlerFunc or httprouter.Handle friendly, maybe you should have been writing a number of wrappers for these handler functions. (also handler function itself).
AuthWrappers (synthesys.AuthWrapper or rt_synthesis.AuthWrapper) are designed to be used as function generator which are acceptable for http.HandleFunc or httprouter.Handle like this:
http.HandleFunc("/some/resource", someAuthWrapper(yourHandler))
//or
router.GET("/api/path/somewhere", someAuthWrapper(yourHandler))Many of wrapper functions in this package are implemented in AuthWrapper type, including basic authentication, IP filtering, header validation, and so on.
You can apply single basic authentication for a simple but a little secured route with the following snippet:
package example
import (
"github.com/g1eng/httpfilter/auth/basic"
"github.com/julienschmidt/httprouter"
"net/http"
)
func yourHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
//some code here
}
func herHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
//any code here
}
func route() *httprouter.Router {
router := httprouter.New()
b := basic.NewBasicAuth("/path/to/htpasswd/or/credential/line")
router.GET("/some/public/resource", yourHandler)
router.GET("/some/secured/resource", b.RouterAuthenticate(herHandler))
return router
}Sometime, we need two or more request validators for a protected/hardened resource(s).
In such cases you can use httpfilter/synthesis to apply multiple authorization/validation mechanisms to users' traffic.
Two or more effects of AuthWrapper can be synthesized with AuthAnd, AuthOR or AuthAll.
You can write the synthesis of conditional checks with several AuthWrappers like this:
package example
import (
"github.com/g1eng/httpfilter/auth/basic"
"github.com/g1eng/httpfilter/ipfilter"
"github.com/g1eng/httpfilter/synthesis"
"net/http"
)
func yourHandler(w http.ResponseWriter, r *http.Request) {
//some code here
}
func herHandler(w http.ResponseWriter, r *http.Request) {
//any code here
}
func Serve() {
s := http.Server{
Addr: "0.0.0.0:8080",
}
AND := synthesis.AuthAND
defaultFilter := ipfilter.NewIPFilter(true, []string{"192.0.0.0/24"}).Authorize
managedFilter := basic.NewBasicAuth("/path/to/htpasswd/or/credential/line").Authenticate
//users must be authorized with two factor to access to protected resources for dualAuth
dualAuth := AND(defaultFilter, managedFilter)
http.HandleFunc("/o/ha", defaultFilter(yourHandler))
http.HandleFunc("/o/con", dualAuth(herHandler))
_ = s.ListenAndServe()
}For httprouter, import synthesis/rt_synthesis package and use Auth* declared in that package:
package example
import (
"github.com/g1eng/httpfilter/auth/basic"
"github.com/g1eng/httpfilter/ipfilter"
"github.com/g1eng/httpfilter/synthesis/rt_synthesis"
"github.com/julienschmidt/httprouter"
"net/http"
)
func yourHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
//some code here
}
func herHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
//any code here
}
func Route() *httprouter.Router {
router := httprouter.New()
defaultFilter := ipfilter.NewIPFilter(true, []string{"192.0.0.0/24"}).RouterAuthorize
managerFilter := basic.NewBasicAuth("/path/to/htpasswd/or/credential/line").RouterAuthenticate
dualAuth := rt_synthesis.AuthAND(defaultFilter, managerFilter)
router.GET("/some/corp/resource", defaultFilter(yourHandler))
router.GET("/some/mgnt/resource", dualAuth(herHandler))
return router
}On my nearest experience, different project in different requirements with different stakeholders, share similar access control mechanisms that satisfy any of VIP's request within possible costs. How do you think about such shared implementation can be reliable, full-featured, open and popular one?
This project is a proposal for generic access control wrapper mechanism on golang-based web applications.
- hardening on local session storage (and planning to import external popular session management mechanisms)
- redis token caching
If you need any documentation enhancement, make issue or PR and post your request about desired additional topics!
You are welcomed to propose any type of commitment to this project! Contact from the issue page in open style and share your ideas about this package.
Apache 2.0.