IAM: Set userId in context logs from ErrTokenNeedsRotation (#118066)

This commit is contained in:
xavi
2026-02-16 08:52:50 +00:00
committed by GitHub
parent a80e6ce73f
commit 42f464d703
7 changed files with 34 additions and 8 deletions
+2 -1
View File
@@ -96,7 +96,8 @@ func (hs *HTTPServer) CookieOptionsFromCfg() cookies.CookieOptions {
}
func (hs *HTTPServer) LoginView(c *contextmodel.ReqContext) {
if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
var tokenRotationErr authn.TokenNeedsRotationError
if errors.As(c.LookupTokenErr, &tokenRotationErr) {
c.Redirect(hs.Cfg.AppSubURL + "/")
return
}
+2 -1
View File
@@ -48,7 +48,8 @@ func notAuthorized(c *contextmodel.ReqContext) {
writeRedirectCookie(c)
}
if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
var tokenRotationErr authn.TokenNeedsRotationError
if errors.As(c.LookupTokenErr, &tokenRotationErr) {
if !c.UseSessionStorageRedirect {
c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
return
+2 -1
View File
@@ -146,7 +146,8 @@ func unauthorized(c *contextmodel.ReqContext) {
writeRedirectCookie(c)
}
if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
var tokenRotationErr authn.TokenNeedsRotationError
if errors.As(c.LookupTokenErr, &tokenRotationErr) {
if !c.UseSessionStorageRedirect {
c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
return
+2 -1
View File
@@ -121,7 +121,8 @@ func (s *Service) Authenticate(ctx context.Context, r *authn.Request) (*authn.Id
if err != nil {
// Note: special case for token rotation
// We don't want to fallthrough in this case
if errors.Is(err, authn.ErrTokenNeedsRotation) {
var tokenRotationErr authn.TokenNeedsRotationError
if errors.As(err, &tokenRotationErr) {
return nil, err
}
+1 -1
View File
@@ -60,7 +60,7 @@ func (s *Session) Authenticate(ctx context.Context, r *authn.Request) (*authn.Id
}
if token.NeedsRotation(time.Duration(s.cfg.TokenRotationIntervalMinutes) * time.Minute) {
return nil, authn.ErrTokenNeedsRotation.Errorf("token needs to be rotated")
return nil, authn.NewTokenNeedsRotationError(token.UserId)
}
ident := &authn.Identity{
+15 -1
View File
@@ -3,9 +3,23 @@ package authn
import "github.com/grafana/grafana/pkg/apimachinery/errutil"
var (
ErrTokenNeedsRotation = errutil.Unauthorized("session.token.rotate", errutil.WithLogLevel(errutil.LevelDebug))
errTokenNeedsRotation = errutil.Unauthorized("session.token.rotate", errutil.WithLogLevel(errutil.LevelDebug))
ErrUnsupportedClient = errutil.BadRequest("auth.client.unsupported")
ErrClientNotConfigured = errutil.BadRequest("auth.client.notConfigured")
ErrUnsupportedIdentity = errutil.NotImplemented("auth.identity.unsupported")
ErrExpiredAccessToken = errutil.Unauthorized("oauth.expired-token", errutil.WithPublicMessage("OAuth access token expired"))
)
type errutilError = errutil.Error
type TokenNeedsRotationError struct {
errutilError
UserID int64
}
func NewTokenNeedsRotationError(userID int64) TokenNeedsRotationError {
return TokenNeedsRotationError{
errutilError: errTokenNeedsRotation.Errorf("token needs to be rotated"),
UserID: userID,
}
}
+10 -2
View File
@@ -3,6 +3,7 @@ package contexthandler
import (
"context"
"errors"
"fmt"
"net/http"
@@ -129,10 +130,16 @@ func (h *ContextHandler) setRequestContext(ctx context.Context) context.Context
reqContext.Logger = reqContext.Logger.New("traceID", traceID)
}
var userId int64
id, err := h.authenticator.Authenticate(ctx, &authn.Request{HTTPRequest: reqContext.Req})
if err != nil {
// Hack: set all errors on LookupTokenErr, so we can check it in auth middlewares
reqContext.LookupTokenErr = err
var tokenRotationErr authn.TokenNeedsRotationError
if errors.As(err, &tokenRotationErr) {
userId = tokenRotationErr.UserID
}
} else {
reqContext.SignedInUser = id.SignedInUser()
reqContext.UserToken = id.SessionToken
@@ -140,15 +147,16 @@ func (h *ContextHandler) setRequestContext(ctx context.Context) context.Context
reqContext.AllowAnonymous = reqContext.IsAnonymous
reqContext.IsRenderCall = id.IsAuthenticatedBy(login.RenderModule)
ctx = identity.WithRequester(ctx, id)
userId = reqContext.UserID
}
h.excludeSensitiveHeadersFromRequest(reqContext.Req)
reqContext.Logger = reqContext.Logger.New("userId", reqContext.UserID, "orgId", reqContext.OrgID, "uname", reqContext.Login)
reqContext.Logger = reqContext.Logger.New("userId", userId, "orgId", reqContext.OrgID, "uname", reqContext.Login)
span.AddEvent("user", trace.WithAttributes(
attribute.String("uname", reqContext.Login),
attribute.Int64("orgId", reqContext.OrgID),
attribute.Int64("userId", reqContext.UserID),
attribute.Int64("userId", userId),
))
if h.cfg.IDResponseHeaderEnabled && reqContext.SignedInUser != nil {