Adds JWT token generation methods

- Generates token encoded with user and save it to store
- Updated token generation method usage in Corredor and Impersonalization
This commit is contained in:
Vivek Patel
2021-09-22 21:09:55 +02:00
committed by Denis Arh
parent 5ac8790bc8
commit 54cbfe20d8
6 changed files with 161 additions and 8 deletions
+6
View File
@@ -1,6 +1,7 @@
package auth
import (
"context"
"github.com/dgrijalva/jwt-go"
"net/http"
)
@@ -17,8 +18,13 @@ type (
Encode(identity Identifiable, scope ...string) string
}
TokenGenerator interface {
Generate(ctx context.Context, identity Identifiable) (string, error)
}
TokenHandler interface {
TokenEncoder
TokenGenerator
Authenticate(token string) (jwt.MapClaims, error)
HttpVerifier() func(http.Handler) http.Handler
HttpAuthenticator() func(http.Handler) http.Handler
+74 -2
View File
@@ -2,7 +2,10 @@ package auth
import (
"context"
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/system/types"
"net/http"
"strconv"
"strings"
@@ -20,17 +23,27 @@ type (
expiry time.Duration
tokenAuth *jwtauth.JWTAuth
}
tokenStore interface {
CreateAuthOa2token(ctx context.Context, rr ...*types.AuthOa2token) error
UpsertAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error
}
ExtraReqInfo struct {
RemoteAddr string
UserAgent string
}
)
var (
DefaultJwtHandler TokenHandler
DefaultJwtStore tokenStore
)
func SetupDefault(secret string, expiry time.Duration) {
// Use JWT secret for hmac signer for now
DefaultSigner = HmacSigner(secret)
DefaultJwtHandler, _ = JWT(secret, expiry)
}
func JWT(secret string, expiry time.Duration) (tkn *token, err error) {
@@ -46,6 +59,13 @@ func JWT(secret string, expiry time.Duration) (tkn *token, err error) {
return tkn, nil
}
// SetJWTStore set store for JWT
// @todo find better way to initiate store,
// it mainly used for generating and storing accessToken for impersonate and corredor, Ref: j.Generate()
func SetJWTStore(store tokenStore) {
DefaultJwtStore = store
}
func (t *token) Authenticate(token string) (jwt.MapClaims, error) {
dt, err := t.tokenAuth.Decode(token)
if err != nil {
@@ -88,7 +108,6 @@ func (t *token) Encode(i Identifiable, scope ...string) string {
}
func (t *token) encode(i Identifiable, clientID uint64, scope ...string) string {
roles := ""
for _, r := range i.Roles() {
roles += fmt.Sprintf(" %d", r)
@@ -132,6 +151,59 @@ func (t *token) HttpAuthenticator() func(http.Handler) http.Handler {
}
}
func (t *token) Generate(ctx context.Context, i Identifiable) (tokenString string, err error) {
var (
eti = GetExtraReqInfoFromContext(ctx)
oa2t = &types.AuthOa2token{
ID: id.Next(),
CreatedAt: time.Now().Round(time.Second),
RemoteAddr: eti.RemoteAddr,
UserAgent: eti.UserAgent,
}
acc = &types.AuthConfirmedClient{
ConfirmedAt: oa2t.CreatedAt,
}
)
tokenString = t.Encode(i)
oa2t.Access = tokenString
oa2t.ExpiresAt = oa2t.CreatedAt.Add(t.expiry)
if oa2t.Data, err = json.Marshal(oa2t); err != nil {
return
}
// extend this with the client
oa2t.ClientID = 0
// copy client id to auth client confirmation
acc.ClientID = oa2t.ClientID
if oa2t.UserID, _ = ExtractFromSubClaim(i.String()); oa2t.UserID == 0 {
// UserID stores collection of IDs: user's ID and set of all roles' user is member of
return "", fmt.Errorf("could not parse user ID from token")
}
// copy user id to auth client confirmation
acc.UserID = oa2t.UserID
if err = DefaultJwtStore.UpsertAuthConfirmedClient(ctx, acc); err != nil {
return
}
return tokenString, DefaultJwtStore.CreateAuthOa2token(ctx, oa2t)
}
func GetExtraReqInfoFromContext(ctx context.Context) ExtraReqInfo {
eti := ctx.Value(ExtraReqInfo{})
if eti != nil {
return eti.(ExtraReqInfo)
} else {
return ExtraReqInfo{}
}
}
// ClaimsToIdentity decodes sub & roles claims into identity
func ClaimsToIdentity(c jwt.MapClaims) (i *identity) {
var (
+18 -3
View File
@@ -104,7 +104,8 @@ type (
}
authTokenMaker interface {
Encode(auth.Identifiable, ...string) string
auth.TokenEncoder
auth.TokenGenerator
}
)
@@ -653,6 +654,8 @@ func (svc service) exec(ctx context.Context, script string, runAs string, args S
zap.String("eventType", args.EventType()),
zap.String("resourceType", args.ResourceType()),
)
token string
)
log.Debug("triggered")
@@ -716,7 +719,13 @@ func (svc service) exec(ctx context.Context, script string, runAs string, args S
return
}
if err = encodeArguments(req.Args, "authToken", svc.authTokenMaker.Encode(definer)); err != nil {
// Generate and save the token
token, err = svc.authTokenMaker.Generate(ctx, definer)
if err != nil {
return
}
if err = encodeArguments(req.Args, "authToken", token); err != nil {
return
}
@@ -728,7 +737,13 @@ func (svc service) exec(ctx context.Context, script string, runAs string, args S
return
}
if err = encodeArguments(req.Args, "authToken", svc.authTokenMaker.Encode(invoker)); err != nil {
// Generate and save the token
token, err = svc.authTokenMaker.Generate(ctx, invoker)
if err != nil {
return
}
if err = encodeArguments(req.Args, "authToken", token); err != nil {
return
}
}