Feature: add custom id claim (#667)

This feature allows using the custom claim in the JWT token as a user ID.

Refactor claims extractor with options support

Add is_current to the user API response
This commit is contained in:
Givi Khojanashvili
2023-02-03 21:47:20 +01:00
committed by GitHub
parent 494e56d1be
commit 3ec8274b8e
32 changed files with 474 additions and 305 deletions
+20 -7
View File
@@ -3,11 +3,11 @@ package server
import (
"context"
"fmt"
"github.com/netbirdio/netbird/management/server/telemetry"
gPeer "google.golang.org/grpc/peer"
"strings"
"time"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/management/server/http/middleware"
"github.com/netbirdio/netbird/management/server/jwtclaims"
@@ -31,12 +31,14 @@ type GRPCServer struct {
config *Config
turnCredentialsManager TURNCredentialsManager
jwtMiddleware *middleware.JWTMiddleware
jwtClaimsExtractor *jwtclaims.ClaimsExtractor
appMetrics telemetry.AppMetrics
}
// NewServer creates a new Management server
func NewServer(config *Config, accountManager AccountManager, peersUpdateManager *PeersUpdateManager,
turnCredentialsManager TURNCredentialsManager, appMetrics telemetry.AppMetrics) (*GRPCServer, error) {
turnCredentialsManager TURNCredentialsManager, appMetrics telemetry.AppMetrics,
) (*GRPCServer, error) {
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
return nil, err
@@ -66,6 +68,16 @@ func NewServer(config *Config, accountManager AccountManager, peersUpdateManager
}
}
var audience, userIDClaim string
if config.HttpConfig != nil {
audience = config.HttpConfig.AuthAudience
userIDClaim = config.HttpConfig.AuthUserIDClaim
}
jwtClaimsExtractor := jwtclaims.NewClaimsExtractor(
jwtclaims.WithAudience(audience),
jwtclaims.WithUserIDClaim(userIDClaim),
)
return &GRPCServer{
wgKey: key,
// peerKey -> event channel
@@ -74,6 +86,7 @@ func NewServer(config *Config, accountManager AccountManager, peersUpdateManager
config: config,
turnCredentialsManager: turnCredentialsManager,
jwtMiddleware: jwtMiddleware,
jwtClaimsExtractor: jwtClaimsExtractor,
appMetrics: appMetrics,
}, nil
}
@@ -113,7 +126,7 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
peer, err := s.accountManager.GetPeerByKey(peerKey.String())
if err != nil {
p, _ := gPeer.FromContext(srv.Context())
p, _ := gRPCPeer.FromContext(srv.Context())
msg := status.Errorf(codes.PermissionDenied, "provided peer with the key wgPubKey %s is not registered, remote addr is %s", peerKey.String(), p.Addr.String())
log.Debug(msg)
return msg
@@ -122,7 +135,7 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
syncReq := &proto.SyncRequest{}
err = encryption.DecryptMessage(peerKey, s.wgKey, req.Body, syncReq)
if err != nil {
p, _ := gPeer.FromContext(srv.Context())
p, _ := gRPCPeer.FromContext(srv.Context())
msg := status.Errorf(codes.InvalidArgument, "invalid request message from %s,remote addr is %s", peerKey.String(), p.Addr.String())
log.Debug(msg)
return msg
@@ -200,7 +213,7 @@ func (s *GRPCServer) registerPeer(peerKey wgtypes.Key, req *proto.LoginRequest)
if err != nil {
return nil, status.Errorf(codes.Internal, "invalid jwt token, err: %v", err)
}
claims := jwtclaims.ExtractClaimsWithToken(token, s.config.HttpConfig.AuthAudience)
claims := s.jwtClaimsExtractor.FromToken(token)
userID = claims.UserId
// we need to call this method because if user is new, we will automatically add it to existing or create a new account
_, _, err = s.accountManager.GetAccountFromToken(claims)
@@ -305,7 +318,7 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p
// peer doesn't exist -> check if setup key was provided
if loginReq.GetJwtToken() == "" && loginReq.GetSetupKey() == "" {
// absent setup key or jwt -> permission denied
p, _ := gPeer.FromContext(ctx)
p, _ := gRPCPeer.FromContext(ctx)
msg := status.Errorf(codes.PermissionDenied,
"provided peer with the key wgPubKey %s is not registered and no setup key or jwt was provided,"+
" remote addr is %s", peerKey.String(), p.Addr.String())