diff --git a/internal/grpc/interceptors/auth/auth.go b/internal/grpc/interceptors/auth/auth.go index 353023d68b..927eab3713 100644 --- a/internal/grpc/interceptors/auth/auth.go +++ b/internal/grpc/interceptors/auth/auth.go @@ -209,11 +209,12 @@ func dismantleToken(ctx context.Context, tkn string, req interface{}, mgr token. return nil, err } - if fetchUserGroups { + if sharedconf.SkipUserGroupsInToken() && fetchUserGroups { groups, err := getUserGroups(ctx, u, gatewayAddr) - if err == nil { - u.Groups = groups + if err != nil { + return nil, err } + u.Groups = groups } // Check if access to the resource is in the scope of the token diff --git a/internal/grpc/services/gateway/authprovider.go b/internal/grpc/services/gateway/authprovider.go index fe9c1e680a..f9705cb49d 100644 --- a/internal/grpc/services/gateway/authprovider.go +++ b/internal/grpc/services/gateway/authprovider.go @@ -38,6 +38,7 @@ import ( "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/rgrpc/status" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/pkg/sharedconf" "github.com/cs3org/reva/pkg/utils" "github.com/pkg/errors" "google.golang.org/grpc/metadata" @@ -98,6 +99,11 @@ func (s *svc) Authenticate(ctx context.Context, req *gateway.AuthenticateRequest }, nil } + u := res.User + if sharedconf.SkipUserGroupsInToken() { + u.Groups = []string{} + } + // We need to expand the scopes of lightweight accounts, user shares and // public shares, for which we need to retrieve the receieved shares and stat // the resources referenced by these. Since the current scope can do that, @@ -180,8 +186,12 @@ func (s *svc) WhoAmI(ctx context.Context, req *gateway.WhoAmIRequest) (*gateway. Status: status.NewUnauthenticated(ctx, err, "error dismantling token"), }, nil } - groupsRes, err := s.GetUserGroups(ctx, &userpb.GetUserGroupsRequest{UserId: u.Id}) - if err == nil { + + if sharedconf.SkipUserGroupsInToken() { + groupsRes, err := s.GetUserGroups(ctx, &userpb.GetUserGroupsRequest{UserId: u.Id}) + if err != nil { + return nil, err + } u.Groups = groupsRes.Groups } diff --git a/internal/http/interceptors/auth/auth.go b/internal/http/interceptors/auth/auth.go index e52cc7a032..57b616c13c 100644 --- a/internal/http/interceptors/auth/auth.go +++ b/internal/http/interceptors/auth/auth.go @@ -247,17 +247,22 @@ func New(m map[string]interface{}, unprotected []string) (global.Middleware, err return } - var groups []string - if groupsIf, err := userGroupsCache.Get(u.Id.OpaqueId); err == nil { - groups = groupsIf.([]string) - } else { - groupsRes, err := client.GetUserGroups(ctx, &userpb.GetUserGroupsRequest{UserId: u.Id}) - if err == nil { + if sharedconf.SkipUserGroupsInToken() { + var groups []string + if groupsIf, err := userGroupsCache.Get(u.Id.OpaqueId); err == nil { + groups = groupsIf.([]string) + } else { + groupsRes, err := client.GetUserGroups(ctx, &userpb.GetUserGroupsRequest{UserId: u.Id}) + if err != nil { + log.Error().Err(err).Msg("error retrieving user groups") + w.WriteHeader(http.StatusInternalServerError) + return + } groups = groupsRes.Groups _ = userGroupsCache.SetWithExpire(u.Id.OpaqueId, groupsRes.Groups, 3600*time.Second) } + u.Groups = groups } - u.Groups = groups // ensure access to the resource is allowed ok, err := scope.VerifyScope(tokenScope, r.URL.Path) diff --git a/pkg/sharedconf/sharedconf.go b/pkg/sharedconf/sharedconf.go index 0025b305c0..d458c9bc22 100644 --- a/pkg/sharedconf/sharedconf.go +++ b/pkg/sharedconf/sharedconf.go @@ -28,9 +28,10 @@ import ( var sharedConf = &conf{} type conf struct { - JWTSecret string `mapstructure:"jwt_secret"` - GatewaySVC string `mapstructure:"gatewaysvc"` - DataGateway string `mapstructure:"datagateway"` + JWTSecret string `mapstructure:"jwt_secret"` + GatewaySVC string `mapstructure:"gatewaysvc"` + DataGateway string `mapstructure:"datagateway"` + SkipUserGroupsInToken bool `mapstructure:"skip_user_groups_in_token"` } // Decode decodes the configuration. @@ -86,3 +87,8 @@ func GetDataGateway(val string) string { } return val } + +// SkipUserGroupsInToken returns whether to skip encoding user groups in the access tokens. +func SkipUserGroupsInToken() bool { + return sharedConf.SkipUserGroupsInToken +} diff --git a/pkg/token/manager/jwt/jwt.go b/pkg/token/manager/jwt/jwt.go index 314effba9d..e54df4dae9 100644 --- a/pkg/token/manager/jwt/jwt.go +++ b/pkg/token/manager/jwt/jwt.go @@ -87,12 +87,6 @@ func New(value map[string]interface{}) (token.Manager, error) { func (m *manager) MintToken(ctx context.Context, u *user.User, scope map[string]*auth.Scope) (string, error) { ttl := time.Duration(m.conf.Expires) * time.Second - - // We don't encode the groups in the JWT token to reduce its size. - // Whenever any services need to enquire about these, they need to make a - // request to the userprovider service and cache these on their end. - u.Groups = []string{} - claims := claims{ StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(ttl).Unix(),