A set of conditional access control wrappers for golang-based web application, written in httprouter or http.HandlerFunc
.
- variety of handler wrappers implemented in
AuthWrapper
helps you to protect resources forhttp.HandlerFunc
andhttprouter.Handle
. - several authentication providers and session management mechanisms are available in
auth
andsession
package for both ofhttp
andhttprouter
package. - simple IP-based filtering powered by
jpillora/ipfilter
. (thanks!) - AND or OR synthetic wrapper with
httpfilter/syntesis
package, which enables you to apply two or moreAuthWrapper
for single route. (AuthWrapper
is also supported). - Additional header management and built-in CORS support with
header
package (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.Handle
AuthWrapper 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.