diff --git a/pkg/services/auth/idimpl/service.go b/pkg/services/auth/idimpl/service.go index 3c42c5c103b..07c5cc5991d 100644 --- a/pkg/services/auth/idimpl/service.go +++ b/pkg/services/auth/idimpl/service.go @@ -24,8 +24,8 @@ import ( const ( cachePrefix = "id-token" - tokenTTL = 1 * time.Hour - cacheTTL = 58 * time.Minute + tokenTTL = 10 * time.Minute + cacheLeeway = 30 * time.Second ) var _ auth.IDService = (*Service)(nil) @@ -101,7 +101,22 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri return "", err } - if err := s.cache.Set(ctx, cacheKey, []byte(token), cacheTTL); err != nil { + parsed, err := jwt.ParseSigned(token) + if err != nil { + s.metrics.failedTokenSigningCounter.Inc() + return "", err + } + + extracted := auth.IDClaims{} + // We don't need to verify the signature here, we are only intrested in checking + // when the token expires. + if err := parsed.UnsafeClaimsWithoutVerification(&extracted); err != nil { + s.metrics.failedTokenSigningCounter.Inc() + return "", err + } + + expires := time.Until(extracted.Expiry.Time()) + if err := s.cache.Set(ctx, cacheKey, []byte(token), expires-cacheLeeway); err != nil { s.logger.FromContext(ctx).Error("Failed to add id token to cache", "error", err) } diff --git a/pkg/services/auth/idimpl/service_test.go b/pkg/services/auth/idimpl/service_test.go index 7d214231f6c..a5e746904b5 100644 --- a/pkg/services/auth/idimpl/service_test.go +++ b/pkg/services/auth/idimpl/service_test.go @@ -2,9 +2,10 @@ package idimpl import ( "context" - "encoding/json" "testing" + "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v3/jwt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -53,11 +54,14 @@ func Test_ProvideService(t *testing.T) { func TestService_SignIdentity(t *testing.T) { signer := &idtest.MockSigner{ SignIDTokenFn: func(_ context.Context, claims *auth.IDClaims) (string, error) { - data, err := json.Marshal(claims) - if err != nil { - return "", err - } - return string(data), nil + key := []byte("key") + s, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: key}, nil) + require.NoError(t, err) + + token, err := jwt.Signed(s).Claims(claims).CompactSerialize() + require.NoError(t, err) + + return token, nil }, } @@ -81,8 +85,11 @@ func TestService_SignIdentity(t *testing.T) { token, err := s.SignIdentity(context.Background(), &authn.Identity{ID: "user:1"}) require.NoError(t, err) + parsed, err := jwt.ParseSigned(token) + require.NoError(t, err) + claims := &auth.IDClaims{} - require.NoError(t, json.Unmarshal([]byte(token), claims)) + require.NoError(t, parsed.UnsafeClaimsWithoutVerification(&claims)) assert.Equal(t, login.AzureADAuthModule, claims.AuthenticatedBy) }) }