Adds a jwt middleware
It is not certain that it is final, as the jwt is just an interface{}
This commit is contained in:
76
jwt.go
Normal file
76
jwt.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package narco
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/codemodus/chain"
|
||||
"golang.org/x/net/context"
|
||||
"ponyo.epfl.ch/gitlab/alexandre.tuleu/narco/jwt"
|
||||
)
|
||||
|
||||
type JWT struct {
|
||||
signer jwt.Signer
|
||||
}
|
||||
|
||||
const (
|
||||
jwtKeyGenerator narcoKey = 2
|
||||
jwtKeyOutput narcoKey = 3
|
||||
)
|
||||
|
||||
func (j *JWT) Wrap() func(chain.Handler) chain.Handler {
|
||||
return func(other chain.Handler) chain.Handler {
|
||||
return chain.HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, req *http.Request) {
|
||||
tokenGenerator, ok := ctx.Value(jwtKeyGenerator).(TokenCreator)
|
||||
|
||||
if tokenGenerator == nil || ok == false {
|
||||
//we did not register a token we ignore all processing
|
||||
other.ServeHTTPContext(ctx, rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
// check for the header
|
||||
tokenStr, ok := req.Header["Authorization"]
|
||||
if ok == false {
|
||||
// no Authorization header, we are just not
|
||||
// authentified, we process down, no token added
|
||||
other.ServeHTTPContext(ctx, rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
if len(tokenStr) != 1 || strings.HasPrefix(tokenStr[0], "Bearer ") == false {
|
||||
Error(ctx, rw, fmt.Errorf("Invalid Authorization HTTP Header %v", tokenStr), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
tkData := strings.TrimPrefix(tokenStr[0], "Bearer ")
|
||||
|
||||
//parse the desired token, with signature checking
|
||||
token := tokenGenerator()
|
||||
err := jwt.DecodeJWS([]byte(tkData), token, j.signer)
|
||||
if err != nil {
|
||||
Error(ctx, rw, err, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// we process down the pipeline, with the token added to
|
||||
// context
|
||||
other.ServeHTTPContext(context.WithValue(ctx, jwtKeyOutput, token), rw, req)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func GetJwt(ctx context.Context) interface{} {
|
||||
return ctx.Value(jwtKeyOutput)
|
||||
}
|
||||
|
||||
//A Token Creator should produce a new pointer to a desired token
|
||||
//struct
|
||||
type TokenCreator func() interface{}
|
||||
|
||||
// RegisterJwtType should be used to register the token rtyope
|
||||
// expected in the context. TokenCreator should allocate a new,
|
||||
// unparsed token.
|
||||
func RegisterJwtType(ctx context.Context, generator TokenCreator) context.Context {
|
||||
return context.WithValue(ctx, jwtKeyGenerator, generator)
|
||||
}
|
||||
Reference in New Issue
Block a user