feat(auth): accept clock skew for token validation
arcad/emissary/pipeline/head Something is wrong with the build of this commit
Details
arcad/emissary/pipeline/head Something is wrong with the build of this commit
Details
This commit is contained in:
parent
d02eb91b11
commit
7d551a8312
|
@ -14,8 +14,11 @@ import (
|
||||||
"gitlab.com/wpetit/goweb/logger"
|
"gitlab.com/wpetit/goweb/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DefaultAcceptableSkew = 5 * time.Minute
|
||||||
|
|
||||||
type Authenticator struct {
|
type Authenticator struct {
|
||||||
repo datastore.AgentRepository
|
repo datastore.AgentRepository
|
||||||
|
acceptableSkew time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate implements auth.Authenticator.
|
// Authenticate implements auth.Authenticator.
|
||||||
|
@ -72,6 +75,7 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
|
||||||
[]byte(rawToken),
|
[]byte(rawToken),
|
||||||
jwt.WithKeySet(agent.KeySet.Set, jws.WithRequireKid(false)),
|
jwt.WithKeySet(agent.KeySet.Set, jws.WithRequireKid(false)),
|
||||||
jwt.WithValidate(true),
|
jwt.WithValidate(true),
|
||||||
|
jwt.WithAcceptableSkew(a.acceptableSkew),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
|
@ -91,9 +95,10 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthenticator(repo datastore.AgentRepository) *Authenticator {
|
func NewAuthenticator(repo datastore.AgentRepository, acceptableSkew time.Duration) *Authenticator {
|
||||||
return &Authenticator{
|
return &Authenticator{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
acceptableSkew: acceptableSkew,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/auth"
|
"forge.cadoles.com/Cadoles/emissary/internal/auth"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
||||||
|
@ -11,9 +12,12 @@ import (
|
||||||
"gitlab.com/wpetit/goweb/logger"
|
"gitlab.com/wpetit/goweb/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DefaultAcceptableSkew = 5 * time.Minute
|
||||||
|
|
||||||
type Authenticator struct {
|
type Authenticator struct {
|
||||||
keys jwk.Set
|
keys jwk.Set
|
||||||
issuer string
|
issuer string
|
||||||
|
acceptableSkew time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate implements auth.Authenticator.
|
// Authenticate implements auth.Authenticator.
|
||||||
|
@ -30,7 +34,7 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
|
||||||
return nil, errors.WithStack(auth.ErrUnauthenticated)
|
return nil, errors.WithStack(auth.ErrUnauthenticated)
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := parseToken(ctx, a.keys, a.issuer, rawToken)
|
token, err := parseToken(ctx, a.keys, a.issuer, rawToken, a.acceptableSkew)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
@ -57,10 +61,11 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthenticator(keys jwk.Set, issuer string) *Authenticator {
|
func NewAuthenticator(keys jwk.Set, issuer string, acceptableSkew time.Duration) *Authenticator {
|
||||||
return &Authenticator{
|
return &Authenticator{
|
||||||
keys: keys,
|
keys: keys,
|
||||||
issuer: issuer,
|
issuer: issuer,
|
||||||
|
acceptableSkew: acceptableSkew,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,13 @@ import (
|
||||||
|
|
||||||
const keyRole = "role"
|
const keyRole = "role"
|
||||||
|
|
||||||
func parseToken(ctx context.Context, keys jwk.Set, issuer string, rawToken string) (jwt.Token, error) {
|
func parseToken(ctx context.Context, keys jwk.Set, issuer string, rawToken string, acceptableSkew time.Duration) (jwt.Token, error) {
|
||||||
token, err := jwt.Parse(
|
token, err := jwt.Parse(
|
||||||
[]byte(rawToken),
|
[]byte(rawToken),
|
||||||
jwt.WithKeySet(keys, jws.WithRequireKid(false)),
|
jwt.WithKeySet(keys, jws.WithRequireKid(false)),
|
||||||
jwt.WithIssuer(issuer),
|
jwt.WithIssuer(issuer),
|
||||||
jwt.WithValidate(true),
|
jwt.WithValidate(true),
|
||||||
|
jwt.WithAcceptableSkew(acceptableSkew),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
|
|
|
@ -105,8 +105,8 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(auth.Middleware(
|
r.Use(auth.Middleware(
|
||||||
thirdparty.NewAuthenticator(keys, string(s.conf.Issuer)),
|
thirdparty.NewAuthenticator(keys, string(s.conf.Issuer), thirdparty.DefaultAcceptableSkew),
|
||||||
agent.NewAuthenticator(s.agentRepo),
|
agent.NewAuthenticator(s.agentRepo, agent.DefaultAcceptableSkew),
|
||||||
))
|
))
|
||||||
|
|
||||||
r.Route("/agents", func(r chi.Router) {
|
r.Route("/agents", func(r chi.Router) {
|
||||||
|
|
Loading…
Reference in New Issue