Auth: Add tracing to auth clients and AuthToken service (#107878)

* Add tracing to auth clients + authtoken svc

* Fix span names

* Fix ext_jwt.go

* Fix idimpl/service

* Update wire_gen.go

* Add tracing to JWT client

* Lint
pull/107973/head
Misi 2 weeks ago committed by GitHub
parent 01269c5dd1
commit 1f3dc0533c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      pkg/server/wire_gen.go
  2. 45
      pkg/services/auth/authimpl/auth_token.go
  3. 20
      pkg/services/auth/idimpl/service.go
  4. 11
      pkg/services/auth/idimpl/service_test.go
  5. 18
      pkg/services/authn/authnimpl/registration.go
  6. 17
      pkg/services/authn/clients/api_key.go
  7. 5
      pkg/services/authn/clients/api_key_test.go
  8. 8
      pkg/services/authn/clients/ext_jwt.go
  9. 3
      pkg/services/authn/clients/ext_jwt_test.go
  10. 13
      pkg/services/authn/clients/grafana.go
  11. 5
      pkg/services/authn/clients/grafana_test.go
  12. 9
      pkg/services/authn/clients/jwt.go
  13. 11
      pkg/services/authn/clients/jwt_test.go
  14. 13
      pkg/services/authn/clients/ldap.go
  15. 16
      pkg/services/authn/clients/ldap_test.go
  16. 17
      pkg/services/authn/clients/oauth.go
  17. 10
      pkg/services/authn/clients/oauth_test.go
  18. 9
      pkg/services/authn/clients/password.go
  19. 3
      pkg/services/authn/clients/password_test.go
  20. 12
      pkg/services/authn/clients/proxy.go
  21. 7
      pkg/services/authn/clients/proxy_test.go
  22. 7
      pkg/services/authn/clients/session.go
  23. 5
      pkg/services/authn/clients/session_test.go

@ -648,7 +648,7 @@ func Initialize(cfg *setting.Cfg, opts Options, apiOpts api.ServerOptions) (*Ser
if err != nil {
return nil, err
}
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer)
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
if err != nil {
@ -1161,7 +1161,7 @@ func InitializeForTest(t sqlutil.ITestDB, testingT interface {
if err != nil {
return nil, err
}
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer)
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
if err != nil {

@ -80,6 +80,9 @@ type UserAuthTokenService struct {
}
func (s *UserAuthTokenService) CreateToken(ctx context.Context, cmd *auth.CreateTokenCommand) (*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.CreateToken")
defer span.End()
token, hashedToken, err := generateAndHashToken(s.cfg.SecretKey)
if err != nil {
return nil, err
@ -136,6 +139,9 @@ func (s *UserAuthTokenService) CreateToken(ctx context.Context, cmd *auth.Create
}
func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken string) (*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.LookupToken")
defer span.End()
hashedToken := hashToken(s.cfg.SecretKey, unhashedToken)
var model userAuthToken
var exists bool
@ -234,6 +240,9 @@ func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken st
}
func (s *UserAuthTokenService) GetTokenByExternalSessionID(ctx context.Context, externalSessionID int64) (*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.GetTokenByExternalSessionID")
defer span.End()
var token userAuthToken
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
exists, err := dbSession.Where("external_session_id = ?", externalSessionID).Get(&token)
@ -258,14 +267,23 @@ func (s *UserAuthTokenService) GetTokenByExternalSessionID(ctx context.Context,
}
func (s *UserAuthTokenService) GetExternalSession(ctx context.Context, externalSessionID int64) (*auth.ExternalSession, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.GetExternalSession")
defer span.End()
return s.externalSessionStore.Get(ctx, externalSessionID)
}
func (s *UserAuthTokenService) FindExternalSessions(ctx context.Context, query *auth.ListExternalSessionQuery) ([]*auth.ExternalSession, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.FindExternalSessions")
defer span.End()
return s.externalSessionStore.List(ctx, query)
}
func (s *UserAuthTokenService) UpdateExternalSession(ctx context.Context, externalSessionID int64, cmd *auth.UpdateExternalSessionCommand) error {
ctx, span := s.tracer.Start(ctx, "authtoken.UpdateExternalSession")
defer span.End()
return s.externalSessionStore.Update(ctx, externalSessionID, cmd)
}
@ -329,6 +347,9 @@ func (s *UserAuthTokenService) RotateToken(ctx context.Context, cmd auth.RotateC
}
func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.UserToken, clientIP net.IP, userAgent string) (*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.rotateToken")
defer span.End()
var clientIPStr string
if clientIP != nil {
clientIPStr = clientIP.String()
@ -385,6 +406,9 @@ func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.User
}
func (s *UserAuthTokenService) RevokeToken(ctx context.Context, token *auth.UserToken, soft bool) error {
ctx, span := s.tracer.Start(ctx, "authtoken.RevokeToken")
defer span.End()
if token == nil {
return auth.ErrUserTokenNotFound
}
@ -434,6 +458,9 @@ func (s *UserAuthTokenService) RevokeToken(ctx context.Context, token *auth.User
}
func (s *UserAuthTokenService) RevokeAllUserTokens(ctx context.Context, userId int64) error {
ctx, span := s.tracer.Start(ctx, "authtoken.RevokeAllUserTokens")
defer span.End()
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
ctxLogger := s.log.FromContext(ctx)
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
@ -466,6 +493,9 @@ func (s *UserAuthTokenService) RevokeAllUserTokens(ctx context.Context, userId i
}
func (s *UserAuthTokenService) BatchRevokeAllUserTokens(ctx context.Context, userIds []int64) error {
ctx, span := s.tracer.Start(ctx, "authtoken.BatchRevokeAllUserTokens")
defer span.End()
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
ctxLogger := s.log.FromContext(ctx)
if len(userIds) == 0 {
@ -507,6 +537,9 @@ func (s *UserAuthTokenService) BatchRevokeAllUserTokens(ctx context.Context, use
}
func (s *UserAuthTokenService) GetUserToken(ctx context.Context, userId, userTokenId int64) (*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserToken")
defer span.End()
var result auth.UserToken
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
var token userAuthToken
@ -526,6 +559,9 @@ func (s *UserAuthTokenService) GetUserToken(ctx context.Context, userId, userTok
}
func (s *UserAuthTokenService) GetUserTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserTokens")
defer span.End()
result := []*auth.UserToken{}
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
var tokens []*userAuthToken
@ -554,6 +590,9 @@ func (s *UserAuthTokenService) GetUserTokens(ctx context.Context, userId int64)
// ActiveTokenCount returns the number of active tokens. If userID is nil, the count is for all users.
func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context, userID *int64) (int64, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.ActiveTokenCount")
defer span.End()
if userID != nil && *userID < 1 {
return 0, errUserIDInvalid
}
@ -574,6 +613,9 @@ func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context, userID *int
}
func (s *UserAuthTokenService) DeleteUserRevokedTokens(ctx context.Context, userID int64, window time.Duration) error {
ctx, span := s.tracer.Start(ctx, "authtoken.DeleteUserRevokedTokens")
defer span.End()
return s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
query := "DELETE FROM user_auth_token WHERE user_id = ? AND revoked_at > 0 AND revoked_at <= ?"
res, err := sess.Exec(query, userID, time.Now().Add(-window).Unix())
@ -592,6 +634,9 @@ func (s *UserAuthTokenService) DeleteUserRevokedTokens(ctx context.Context, user
}
func (s *UserAuthTokenService) GetUserRevokedTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserRevokedTokens")
defer span.End()
result := []*auth.UserToken{}
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
var tokens []*userAuthToken

@ -8,6 +8,7 @@ import (
"github.com/go-jose/go-jose/v3/jwt"
"github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/singleflight"
authnlib "github.com/grafana/authlib/authn"
@ -32,18 +33,18 @@ var _ auth.IDService = (*Service)(nil)
func ProvideService(
cfg *setting.Cfg, signer auth.IDSigner,
cache remotecache.CacheStorage,
authnService authn.Service,
reg prometheus.Registerer,
cache remotecache.CacheStorage, authnService authn.Service,
reg prometheus.Registerer, tracer trace.Tracer,
) *Service {
s := &Service{
cfg: cfg, logger: log.New("id-service"),
signer: signer, cache: cache,
metrics: newMetrics(reg),
nsMapper: request.GetNamespaceMapper(cfg),
tracer: tracer,
}
authnService.RegisterPostAuthHook(s.hook, 140)
authnService.RegisterPostAuthHook(s.SyncIDToken, 140)
return s
}
@ -55,10 +56,14 @@ type Service struct {
cache remotecache.CacheStorage
si singleflight.Group
metrics *metrics
tracer trace.Tracer
nsMapper request.NamespaceMapper
}
func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (string, *authnlib.Claims[authnlib.IDTokenClaims], error) {
ctx, span := s.tracer.Start(ctx, "user.sync.SignIdentity")
defer span.End()
defer func(t time.Time) {
s.metrics.tokenSigningDurationHistogram.Observe(time.Since(t).Seconds())
}(time.Now())
@ -140,10 +145,15 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
}
func (s *Service) RemoveIDToken(ctx context.Context, id identity.Requester) error {
ctx, span := s.tracer.Start(ctx, "user.sync.RemoveIDToken")
defer span.End()
return s.cache.Delete(ctx, getCacheKey(id))
}
func (s *Service) hook(ctx context.Context, identity *authn.Identity, _ *authn.Request) error {
func (s *Service) SyncIDToken(ctx context.Context, identity *authn.Identity, _ *authn.Request) error {
ctx, span := s.tracer.Start(ctx, "user.sync.SyncIDToken")
defer span.End()
// FIXME(kalleep): we should probably lazy load this
token, idClaims, err := s.SignIdentity(ctx, identity)
if err != nil {

@ -11,6 +11,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/idtest"
"github.com/grafana/grafana/pkg/services/authn"
@ -29,7 +30,7 @@ func Test_ProvideService(t *testing.T) {
},
}
_ = ProvideService(setting.NewCfg(), nil, nil, authnService, nil)
_ = ProvideService(setting.NewCfg(), nil, nil, authnService, nil, tracing.InitializeTracerForTest())
assert.True(t, hookRegistered)
})
}
@ -51,7 +52,7 @@ func TestService_SignIdentity(t *testing.T) {
t.Run("should sign identity", func(t *testing.T) {
s := ProvideService(
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
&authntest.FakeService{}, nil,
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
)
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser})
require.NoError(t, err)
@ -61,7 +62,7 @@ func TestService_SignIdentity(t *testing.T) {
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
s := ProvideService(
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
&authntest.FakeService{}, nil,
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
)
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{
ID: "1",
@ -86,7 +87,7 @@ func TestService_SignIdentity(t *testing.T) {
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
s := ProvideService(
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
&authntest.FakeService{}, nil,
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
)
_, gotClaims, err := s.SignIdentity(context.Background(), &authn.Identity{
ID: "1",
@ -106,7 +107,7 @@ func TestService_SignIdentity(t *testing.T) {
t.Run("should sign new token if org role has changed", func(t *testing.T) {
s := ProvideService(
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
&authntest.FakeService{}, nil,
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
)
ident := &authn.Identity{

@ -48,10 +48,10 @@ func ProvideRegistration(
logger := log.New("authn.registration")
authnSvc.RegisterClient(clients.ProvideRender(renderService))
authnSvc.RegisterClient(clients.ProvideAPIKey(apikeyService))
authnSvc.RegisterClient(clients.ProvideAPIKey(apikeyService, tracer))
if cfg.LoginCookieName != "" {
authnSvc.RegisterClient(clients.ProvideSession(cfg, sessionService, authInfoService))
authnSvc.RegisterClient(clients.ProvideSession(cfg, sessionService, authInfoService, tracer))
}
var proxyClients []authn.ProxyClient
@ -59,20 +59,20 @@ func ProvideRegistration(
// always register LDAP if LDAP is enabled in SSO settings
if cfg.LDAPAuthEnabled || features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService)
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService, tracer)
proxyClients = append(proxyClients, ldap)
passwordClients = append(passwordClients, ldap)
}
if !cfg.DisableLogin {
grafana := clients.ProvideGrafana(cfg, userService)
grafana := clients.ProvideGrafana(cfg, userService, tracer)
proxyClients = append(proxyClients, grafana)
passwordClients = append(passwordClients, grafana)
}
// if we have password clients configure check if basic auth or form auth is enabled
if len(passwordClients) > 0 {
passwordClient := clients.ProvidePassword(loginAttempts, passwordClients...)
passwordClient := clients.ProvidePassword(loginAttempts, tracer, passwordClients...)
if cfg.BasicAuthEnabled {
authnSvc.RegisterClient(clients.ProvideBasic(passwordClient))
}
@ -103,7 +103,7 @@ func ProvideRegistration(
}
if cfg.AuthProxy.Enabled && len(proxyClients) > 0 {
proxy, err := clients.ProvideProxy(cfg, cache, proxyClients...)
proxy, err := clients.ProvideProxy(cfg, cache, tracer, proxyClients...)
if err != nil {
logger.Error("Failed to configure auth proxy", "err", err)
} else {
@ -113,16 +113,16 @@ func ProvideRegistration(
if cfg.JWTAuth.Enabled {
orgRoleMapper := connectors.ProvideOrgRoleMapper(cfg, orgService)
authnSvc.RegisterClient(clients.ProvideJWT(jwtService, orgRoleMapper, cfg))
authnSvc.RegisterClient(clients.ProvideJWT(jwtService, orgRoleMapper, cfg, tracer))
}
if cfg.ExtJWTAuth.Enabled {
authnSvc.RegisterClient(clients.ProvideExtendedJWT(cfg))
authnSvc.RegisterClient(clients.ProvideExtendedJWT(cfg, tracer))
}
for name := range socialService.GetOAuthProviders() {
clientName := authn.ClientWithPrefix(name)
authnSvc.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService, features))
authnSvc.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService, features, tracer))
}
if features.IsEnabledGlobally(featuremgmt.FlagProvisioning) {

@ -7,6 +7,8 @@ import (
"strings"
"time"
"go.opentelemetry.io/otel/trace"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/components/apikeygen"
@ -35,16 +37,18 @@ const (
metaKeySkipLastUsed = "keySkipLastUsed"
)
func ProvideAPIKey(apiKeyService apikey.Service) *APIKey {
func ProvideAPIKey(apiKeyService apikey.Service, tracer trace.Tracer) *APIKey {
return &APIKey{
log: log.New(authn.ClientAPIKey),
apiKeyService: apiKeyService,
tracer: tracer,
}
}
type APIKey struct {
log log.Logger
apiKeyService apikey.Service
tracer trace.Tracer
}
func (s *APIKey) Name() string {
@ -52,6 +56,8 @@ func (s *APIKey) Name() string {
}
func (s *APIKey) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
ctx, span := s.tracer.Start(ctx, "authn.apikey.Authenticate")
defer span.End()
key, err := s.getAPIKey(ctx, getTokenFromRequest(r))
if err != nil {
if errors.Is(err, apikeygen.ErrInvalidApiKey) {
@ -84,6 +90,8 @@ func (s *APIKey) IsEnabled() bool {
}
func (s *APIKey) getAPIKey(ctx context.Context, token string) (*apikey.APIKey, error) {
ctx, span := s.tracer.Start(ctx, "authn.apikey.getAPIKey")
defer span.End()
fn := s.getFromToken
if !strings.HasPrefix(token, satokengen.GrafanaPrefix) {
fn = s.getFromTokenLegacy
@ -98,6 +106,8 @@ func (s *APIKey) getAPIKey(ctx context.Context, token string) (*apikey.APIKey, e
}
func (s *APIKey) getFromToken(ctx context.Context, token string) (*apikey.APIKey, error) {
ctx, span := s.tracer.Start(ctx, "authn.apikey.getFromToken")
defer span.End()
decoded, err := satokengen.Decode(token)
if err != nil {
return nil, err
@ -112,6 +122,8 @@ func (s *APIKey) getFromToken(ctx context.Context, token string) (*apikey.APIKey
}
func (s *APIKey) getFromTokenLegacy(ctx context.Context, token string) (*apikey.APIKey, error) {
ctx, span := s.tracer.Start(ctx, "authn.apikey.getFromTokenLegacy")
defer span.End()
decoded, err := apikeygen.Decode(token)
if err != nil {
return nil, err
@ -144,6 +156,9 @@ func (s *APIKey) Priority() uint {
}
func (s *APIKey) Hook(ctx context.Context, identity *authn.Identity, r *authn.Request) error {
ctx, span := s.tracer.Start(ctx, "authn.apikey.Hook") //nolint:ineffassign,staticcheck
defer span.End()
if r.GetMeta(metaKeySkipLastUsed) != "" {
return nil
}

@ -12,6 +12,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/components/apikeygen"
"github.com/grafana/grafana/pkg/components/satokengen"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/apikey/apikeytest"
"github.com/grafana/grafana/pkg/services/authn"
@ -106,7 +107,7 @@ func TestAPIKey_Authenticate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
c := ProvideAPIKey(&apikeytest.Service{ExpectedAPIKey: tt.expectedKey})
c := ProvideAPIKey(&apikeytest.Service{ExpectedAPIKey: tt.expectedKey}, tracing.InitializeTracerForTest())
identity, err := c.Authenticate(context.Background(), tt.req)
if tt.expectedErr != nil {
@ -173,7 +174,7 @@ func TestAPIKey_Test(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
c := ProvideAPIKey(&apikeytest.Service{})
c := ProvideAPIKey(&apikeytest.Service{}, tracing.InitializeTracerForTest())
assert.Equal(t, tt.expected, c.Test(context.Background(), tt.req))
})
}

@ -7,6 +7,7 @@ import (
"strings"
"github.com/go-jose/go-jose/v3/jwt"
"go.opentelemetry.io/otel/trace"
authlib "github.com/grafana/authlib/authn"
claims "github.com/grafana/authlib/types"
@ -41,7 +42,7 @@ var (
)
)
func ProvideExtendedJWT(cfg *setting.Cfg) *ExtendedJWT {
func ProvideExtendedJWT(cfg *setting.Cfg, tracer trace.Tracer) *ExtendedJWT {
keys := authlib.NewKeyRetriever(authlib.KeyRetrieverConfig{
SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl,
})
@ -60,6 +61,7 @@ func ProvideExtendedJWT(cfg *setting.Cfg) *ExtendedJWT {
namespaceMapper: request.GetNamespaceMapper(cfg),
accessTokenVerifier: accessTokenVerifier,
idTokenVerifier: idTokenVerifier,
tracer: tracer,
}
}
@ -69,9 +71,13 @@ type ExtendedJWT struct {
accessTokenVerifier authlib.Verifier[authlib.AccessTokenClaims]
idTokenVerifier authlib.Verifier[authlib.IDTokenClaims]
namespaceMapper request.NamespaceMapper
tracer trace.Tracer
}
func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
ctx, span := s.tracer.Start(ctx, "authn.extjwt.Authenticate")
defer span.End()
jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest)
accessTokenClaims, err := s.accessTokenVerifier.Verify(ctx, jwtToken)

@ -17,6 +17,7 @@ import (
authnlib "github.com/grafana/authlib/authn"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/setting"
)
@ -699,7 +700,7 @@ func setupTestCtx(cfg *setting.Cfg) *testEnv {
}
}
extJwtClient := ProvideExtendedJWT(cfg)
extJwtClient := ProvideExtendedJWT(cfg, tracing.InitializeTracerForTest())
return &testEnv{
s: extJwtClient,

@ -7,6 +7,8 @@ import (
"net/mail"
"strconv"
"go.opentelemetry.io/otel/trace"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/login"
@ -19,13 +21,14 @@ import (
var _ authn.ProxyClient = new(Grafana)
var _ authn.PasswordClient = new(Grafana)
func ProvideGrafana(cfg *setting.Cfg, userService user.Service) *Grafana {
return &Grafana{cfg, userService}
func ProvideGrafana(cfg *setting.Cfg, userService user.Service, tracer trace.Tracer) *Grafana {
return &Grafana{cfg, userService, tracer}
}
type Grafana struct {
cfg *setting.Cfg
userService user.Service
tracer trace.Tracer
}
func (c *Grafana) String() string {
@ -33,6 +36,9 @@ func (c *Grafana) String() string {
}
func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, additional map[string]string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.grafana.AuthenticateProxy") //nolint:ineffassign,staticcheck
defer span.End()
identity := &authn.Identity{
AuthenticatedBy: login.AuthProxyAuthModule,
AuthID: username,
@ -91,6 +97,9 @@ func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, usern
}
func (c *Grafana) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.grafana.AuthenticatePassword")
defer span.End()
usr, err := c.userService.GetByLogin(ctx, &user.GetUserByLoginQuery{LoginOrEmail: username})
if err != nil {
if errors.Is(err, user.ErrUserNotFound) {

@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
@ -97,7 +98,7 @@ func TestGrafana_AuthenticateProxy(t *testing.T) {
cfg := setting.NewCfg()
cfg.AuthProxy.AutoSignUp = true
cfg.AuthProxy.HeaderProperty = tt.proxyProperty
c := ProvideGrafana(cfg, usertest.NewUserServiceFake())
c := ProvideGrafana(cfg, usertest.NewUserServiceFake(), tracing.InitializeTracerForTest())
identity, err := c.AuthenticateProxy(context.Background(), tt.req, tt.username, tt.additional)
assert.ErrorIs(t, err, tt.expectedErr)
@ -175,7 +176,7 @@ func TestGrafana_AuthenticatePassword(t *testing.T) {
userService.ExpectedError = user.ErrUserNotFound
}
c := ProvideGrafana(setting.NewCfg(), userService)
c := ProvideGrafana(setting.NewCfg(), userService, tracing.InitializeTracerForTest())
identity, err := c.AuthenticatePassword(context.Background(), &authn.Request{OrgID: 1}, tt.username, tt.password)
assert.ErrorIs(t, err, tt.expectedErr)
assert.EqualValues(t, tt.expectedIdentity, identity)

@ -5,6 +5,8 @@ import (
"net/http"
"strings"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/login/social/connectors"
@ -30,13 +32,14 @@ var (
"jwt.invalid_role", errutil.WithPublicMessage("Invalid Role in claim"))
)
func ProvideJWT(jwtService auth.JWTVerifierService, orgRoleMapper *connectors.OrgRoleMapper, cfg *setting.Cfg) *JWT {
func ProvideJWT(jwtService auth.JWTVerifierService, orgRoleMapper *connectors.OrgRoleMapper, cfg *setting.Cfg, tracer trace.Tracer) *JWT {
return &JWT{
cfg: cfg,
log: log.New(authn.ClientJWT),
jwtService: jwtService,
orgRoleMapper: orgRoleMapper,
orgMappingCfg: orgRoleMapper.ParseOrgMappingSettings(context.Background(), cfg.JWTAuth.OrgMapping, cfg.JWTAuth.RoleAttributeStrict),
tracer: tracer,
}
}
@ -46,6 +49,7 @@ type JWT struct {
orgMappingCfg connectors.MappingConfiguration
log log.Logger
jwtService auth.JWTVerifierService
tracer trace.Tracer
}
func (s *JWT) Name() string {
@ -53,6 +57,9 @@ func (s *JWT) Name() string {
}
func (s *JWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
ctx, span := s.tracer.Start(ctx, "authn.jwt.Authenticate")
defer span.End()
jwtToken := s.retrieveToken(r.HTTPRequest)
s.stripSensitiveParam(r.HTTPRequest)

@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/login/social/connectors"
"github.com/grafana/grafana/pkg/services/auth/jwt"
"github.com/grafana/grafana/pkg/services/authn"
@ -262,7 +263,7 @@ func TestAuthenticateJWT(t *testing.T) {
jwtClient := ProvideJWT(jwtService,
connectors.ProvideOrgRoleMapper(tc.cfg,
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
tc.cfg)
tc.cfg, tracing.InitializeTracerForTest())
validHTTPReq := &http.Request{
Header: map[string][]string{
jwtHeaderName: {"sample-token"}},
@ -380,7 +381,7 @@ func TestJWTClaimConfig(t *testing.T) {
}
jwtClient := ProvideJWT(jwtService, connectors.ProvideOrgRoleMapper(cfg,
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
cfg)
cfg, tracing.InitializeTracerForTest())
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
OrgID: 1,
HTTPRequest: httpReq,
@ -493,7 +494,7 @@ func TestJWTTest(t *testing.T) {
jwtClient := ProvideJWT(jwtService,
connectors.ProvideOrgRoleMapper(cfg,
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
cfg)
cfg, tracing.InitializeTracerForTest())
httpReq := &http.Request{
URL: &url.URL{RawQuery: "auth_token=" + tc.token},
Header: map[string][]string{
@ -549,7 +550,7 @@ func TestJWTStripParam(t *testing.T) {
jwtClient := ProvideJWT(jwtService,
connectors.ProvideOrgRoleMapper(cfg,
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
cfg)
cfg, tracing.InitializeTracerForTest())
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
OrgID: 1,
HTTPRequest: httpReq,
@ -608,7 +609,7 @@ func TestJWTSubClaimsConfig(t *testing.T) {
jwtClient := ProvideJWT(jwtService,
connectors.ProvideOrgRoleMapper(cfg,
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
cfg)
cfg, tracing.InitializeTracerForTest())
identity, err := jwtClient.Authenticate(context.Background(), &authn.Request{
OrgID: 1,
HTTPRequest: httpReq,

@ -4,6 +4,8 @@ import (
"context"
"errors"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/ldap/multildap"
@ -20,8 +22,8 @@ type ldapService interface {
User(username string) (*login.ExternalUserInfo, error)
}
func ProvideLDAP(cfg *setting.Cfg, ldapService ldapService, userService user.Service, authInfoService login.AuthInfoService) *LDAP {
return &LDAP{cfg, log.New("authn.ldap"), ldapService, userService, authInfoService}
func ProvideLDAP(cfg *setting.Cfg, ldapService ldapService, userService user.Service, authInfoService login.AuthInfoService, tracer trace.Tracer) *LDAP {
return &LDAP{cfg, log.New("authn.ldap"), ldapService, userService, authInfoService, tracer}
}
type LDAP struct {
@ -30,6 +32,7 @@ type LDAP struct {
service ldapService
userService user.Service
authInfoService login.AuthInfoService
tracer trace.Tracer
}
func (c *LDAP) String() string {
@ -37,6 +40,8 @@ func (c *LDAP) String() string {
}
func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, _ map[string]string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.ldap.AuthenticateProxy")
defer span.End()
info, err := c.service.User(username)
if errors.Is(err, multildap.ErrDidNotFindUser) {
return c.disableUser(ctx, username)
@ -50,6 +55,8 @@ func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username
}
func (c *LDAP) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.ldap.AuthenticatePassword")
defer span.End()
info, err := c.service.Login(&login.LoginUserQuery{
Username: username,
Password: password,
@ -75,6 +82,8 @@ func (c *LDAP) AuthenticatePassword(ctx context.Context, r *authn.Request, usern
// disableUser will disable users if they logged in via LDAP previously
func (c *LDAP) disableUser(ctx context.Context, username string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.ldap.disableUser")
defer span.End()
c.logger.Debug("User was not found in the LDAP directory tree", "username", username)
retErr := errIdentityNotFound.Errorf("no user found: %w", multildap.ErrDidNotFindUser)

@ -6,7 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/ldap/multildap"
@ -197,13 +197,13 @@ func setupLDAPTestCase(tt *ldapTestCase) *LDAP {
ExpectedError: tt.expectedAuthInfoErr,
}
c := &LDAP{
cfg: setting.NewCfg(),
logger: log.New("authn.ldap.test"),
service: &service.LDAPFakeService{ExpectedUser: tt.expectedLDAPInfo, ExpectedError: tt.expectedLDAPErr},
userService: userService,
authInfoService: authInfoService,
}
c := ProvideLDAP(
setting.NewCfg(),
&service.LDAPFakeService{ExpectedUser: tt.expectedLDAPInfo, ExpectedError: tt.expectedLDAPErr},
userService,
authInfoService,
tracing.InitializeTracerForTest(),
)
return c
}

@ -12,6 +12,7 @@ import (
"os"
"strings"
"go.opentelemetry.io/otel/trace"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
@ -70,12 +71,14 @@ var (
func ProvideOAuth(
name string, cfg *setting.Cfg, oauthService oauthtoken.OAuthTokenService,
socialService social.Service, settingsProviderService setting.Provider, features featuremgmt.FeatureToggles,
socialService social.Service, settingsProviderService setting.Provider,
features featuremgmt.FeatureToggles, tracer trace.Tracer,
) *OAuth {
providerName := strings.TrimPrefix(name, "auth.client.")
return &OAuth{
name, fmt.Sprintf("oauth_%s", providerName), providerName,
log.New(name), cfg, settingsProviderService, oauthService, socialService, features,
log.New(name), cfg, tracer, settingsProviderService, oauthService,
socialService, features,
}
}
@ -85,6 +88,7 @@ type OAuth struct {
providerName string
log log.Logger
cfg *setting.Cfg
tracer trace.Tracer
settingsProviderSvc setting.Provider
oauthService oauthtoken.OAuthTokenService
@ -97,6 +101,9 @@ func (c *OAuth) Name() string {
}
func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.oauth.Authenticate")
defer span.End()
r.SetMeta(authn.MetaKeyAuthModule, c.moduleName)
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
@ -232,6 +239,9 @@ func (c *OAuth) GetConfig() authn.SSOClientConfig {
}
func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redirect, error) {
ctx, span := c.tracer.Start(ctx, "authn.oauth.RedirectURL") //nolint:ineffassign,staticcheck
defer span.End()
var opts []oauth2.AuthCodeOption
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
@ -274,6 +284,9 @@ func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redir
}
func (c *OAuth) Logout(ctx context.Context, user identity.Requester, sessionToken *auth.UserToken) (*authn.Redirect, bool) {
ctx, span := c.tracer.Start(ctx, "authn.oauth.Logout")
defer span.End()
token := c.oauthService.GetCurrentOAuthToken(ctx, user, sessionToken)
userID, err := identity.UserIdentifier(user.GetID())

@ -16,6 +16,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/login/social/socialtest"
"github.com/grafana/grafana/pkg/services/auth"
@ -296,7 +297,7 @@ func TestOAuth_Authenticate(t *testing.T) {
},
}
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, settingsProvider, featuremgmt.WithFeatures(tt.features...))
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, settingsProvider, featuremgmt.WithFeatures(tt.features...), tracing.InitializeTracerForTest())
identity, err := c.Authenticate(context.Background(), tt.req)
assert.ErrorIs(t, err, tt.expectedErr)
@ -376,7 +377,7 @@ func TestOAuth_RedirectURL(t *testing.T) {
cfg := setting.NewCfg()
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, &setting.OSSImpl{Cfg: cfg}, featuremgmt.WithFeatures())
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, &setting.OSSImpl{Cfg: cfg}, featuremgmt.WithFeatures(), tracing.InitializeTracerForTest())
redirect, err := c.RedirectURL(context.Background(), nil)
assert.ErrorIs(t, err, tt.expectedErr)
@ -489,7 +490,7 @@ func TestOAuth_Logout(t *testing.T) {
fakeSocialSvc := &socialtest.FakeSocialService{
ExpectedAuthInfoProvider: tt.oauthCfg,
}
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures())
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures(), tracing.InitializeTracerForTest())
redirect, ok := c.Logout(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser}, nil)
@ -549,7 +550,8 @@ func TestIsEnabled(t *testing.T) {
nil,
fakeSocialSvc,
&setting.OSSImpl{Cfg: cfg},
featuremgmt.WithFeatures())
featuremgmt.WithFeatures(),
tracing.InitializeTracerForTest())
assert.Equal(t, tt.expected, c.IsEnabled())
})
}

@ -4,6 +4,8 @@ import (
"context"
"errors"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/authn"
@ -18,17 +20,20 @@ var (
var _ authn.PasswordClient = new(Password)
func ProvidePassword(loginAttempts loginattempt.Service, clients ...authn.PasswordClient) *Password {
return &Password{loginAttempts, clients, log.New("authn.password")}
func ProvidePassword(loginAttempts loginattempt.Service, tracer trace.Tracer, clients ...authn.PasswordClient) *Password {
return &Password{loginAttempts, clients, log.New("authn.password"), tracer}
}
type Password struct {
loginAttempts loginattempt.Service
clients []authn.PasswordClient
log log.Logger
tracer trace.Tracer
}
func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.password.AuthenticatePassword")
defer span.End()
r.SetMeta(authn.MetaKeyUsername, username)
ok, err := c.loginAttempts.Validate(ctx, username)

@ -10,6 +10,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/services/loginattempt/loginattempttest"
@ -65,7 +66,7 @@ func TestPassword_AuthenticatePassword(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
c := ProvidePassword(loginattempttest.FakeLoginAttemptService{ExpectedValid: !tt.blockLogin}, tt.clients...)
c := ProvidePassword(loginattempttest.FakeLoginAttemptService{ExpectedValid: !tt.blockLogin}, tracing.InitializeTracerForTest(), tt.clients...)
r := &authn.Request{
OrgID: 12345,
HTTPRequest: &http.Request{

@ -13,6 +13,7 @@ import (
"time"
claims "github.com/grafana/authlib/types"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/infra/log"
@ -45,12 +46,12 @@ var (
_ authn.ContextAwareClient = new(Proxy)
)
func ProvideProxy(cfg *setting.Cfg, cache proxyCache, clients ...authn.ProxyClient) (*Proxy, error) {
func ProvideProxy(cfg *setting.Cfg, cache proxyCache, tracer trace.Tracer, clients ...authn.ProxyClient) (*Proxy, error) {
list, err := parseAcceptList(cfg.AuthProxy.Whitelist)
if err != nil {
return nil, err
}
return &Proxy{log.New(authn.ClientProxy), cfg, cache, clients, list}, nil
return &Proxy{log.New(authn.ClientProxy), cfg, cache, clients, list, tracer}, nil
}
type proxyCache interface {
@ -65,6 +66,7 @@ type Proxy struct {
cache proxyCache
clients []authn.ProxyClient
acceptedIPs []*net.IPNet
tracer trace.Tracer
}
func (c *Proxy) Name() string {
@ -72,6 +74,8 @@ func (c *Proxy) Name() string {
}
func (c *Proxy) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.proxy.Authenticate")
defer span.End()
if !c.isAllowedIP(r) {
return nil, errNotAcceptedIP.Errorf("request ip is not in the configured accept list")
}
@ -115,6 +119,8 @@ func (c *Proxy) IsEnabled() bool {
// See if we have cached the user id, in that case we can fetch the signed-in user and skip sync.
// Error here means that we could not find anything in cache, so we can proceed as usual
func (c *Proxy) retrieveIDFromCache(ctx context.Context, cacheKey string, r *authn.Request) (*authn.Identity, error) {
ctx, span := c.tracer.Start(ctx, "authn.proxy.retrieveIDFromCache")
defer span.End()
entry, err := c.cache.Get(ctx, cacheKey)
if err != nil {
return nil, err
@ -148,6 +154,8 @@ func (c *Proxy) Priority() uint {
}
func (c *Proxy) Hook(ctx context.Context, id *authn.Identity, r *authn.Request) error {
ctx, span := c.tracer.Start(ctx, "authn.proxy.Hook")
defer span.End()
if id.ClientParams.CacheAuthProxyKey == "" {
return nil
}

@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/require"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/setting"
@ -113,7 +114,7 @@ func TestProxy_Authenticate(t *testing.T) {
calledAdditional = additional
return nil, nil
}}
c, err := ProvideProxy(cfg, &fakeCache{expectedErr: errors.New("")}, proxyClient)
c, err := ProvideProxy(cfg, &fakeCache{expectedErr: errors.New("")}, tracing.InitializeTracerForTest(), proxyClient)
require.NoError(t, err)
_, err = c.Authenticate(context.Background(), tt.req)
@ -169,7 +170,7 @@ func TestProxy_Test(t *testing.T) {
cfg := setting.NewCfg()
cfg.AuthProxy.HeaderName = "Proxy-Header"
c, _ := ProvideProxy(cfg, nil, nil, nil)
c, _ := ProvideProxy(cfg, nil, tracing.InitializeTracerForTest(), nil)
assert.Equal(t, tt.expectedOK, c.Test(context.Background(), tt.req))
})
}
@ -208,7 +209,7 @@ func TestProxy_Hook(t *testing.T) {
withRole := func(role string) func(t *testing.T) {
cacheKey := fmt.Sprintf("users:johndoe-%s", role)
return func(t *testing.T) {
c, err := ProvideProxy(cfg, cache, authntest.MockProxyClient{})
c, err := ProvideProxy(cfg, cache, tracing.InitializeTracerForTest(), authntest.MockProxyClient{})
require.NoError(t, err)
userIdentity := &authn.Identity{
ID: "1",

@ -7,6 +7,8 @@ import (
"strconv"
"time"
"go.opentelemetry.io/otel/trace"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/auth"
@ -18,12 +20,14 @@ import (
var _ authn.ContextAwareClient = new(Session)
func ProvideSession(cfg *setting.Cfg, sessionService auth.UserTokenService, authInfoService login.AuthInfoService) *Session {
func ProvideSession(cfg *setting.Cfg, sessionService auth.UserTokenService,
authInfoService login.AuthInfoService, tracer trace.Tracer) *Session {
return &Session{
cfg: cfg,
log: log.New(authn.ClientSession),
sessionService: sessionService,
authInfoService: authInfoService,
tracer: tracer,
}
}
@ -32,6 +36,7 @@ type Session struct {
log log.Logger
sessionService auth.UserTokenService
authInfoService login.AuthInfoService
tracer trace.Tracer
}
func (s *Session) Name() string {

@ -11,6 +11,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/models/usertoken"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
@ -31,7 +32,7 @@ func TestSession_Test(t *testing.T) {
cfg := setting.NewCfg()
cfg.LoginCookieName = ""
cfg.LoginMaxLifetime = 20 * time.Second
s := ProvideSession(cfg, &authtest.FakeUserAuthTokenService{}, &authinfotest.FakeService{})
s := ProvideSession(cfg, &authtest.FakeUserAuthTokenService{}, &authinfotest.FakeService{}, tracing.InitializeTracerForTest())
disabled := s.Test(context.Background(), &authn.Request{HTTPRequest: validHTTPReq})
assert.False(t, disabled)
@ -194,7 +195,7 @@ func TestSession_Authenticate(t *testing.T) {
cfg.LoginCookieName = cookieName
cfg.TokenRotationIntervalMinutes = 10
cfg.LoginMaxLifetime = 20 * time.Second
s := ProvideSession(cfg, tt.fields.sessionService, tt.fields.authInfoService)
s := ProvideSession(cfg, tt.fields.sessionService, tt.fields.authInfoService, tracing.InitializeTracerForTest())
got, err := s.Authenticate(context.Background(), tt.args.r)
require.True(t, (err != nil) == tt.wantErr, err)

Loading…
Cancel
Save