Add OIDC login event (#21650)

Signed-off-by: stonezdj <stone.zhang@broadcom.com>
This commit is contained in:
stonezdj(Daojun Zhang) 2025-02-21 18:18:51 +08:00 committed by GitHub
parent b837bbb716
commit e5e131845e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 4 deletions

View File

@ -24,11 +24,13 @@ import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/controller/event/metadata/commonevent"
ctluser "github.com/goharbor/harbor/src/controller/user"
"github.com/goharbor/harbor/src/core/api"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/oidc"
)
@ -38,6 +40,8 @@ const userInfoKey = "oidc_user_info"
const redirectURLKey = "oidc_redirect_url"
const oidcUserComment = "Onboarded via OIDC provider"
const loginUserOperation = "login_user"
// OIDCController handles requests for OIDC login, callback and user onboard
type OIDCController struct {
api.BaseController
@ -208,6 +212,19 @@ func (oc *OIDCController) Callback() {
redirectURLStr = "/"
}
oc.Controller.Redirect(redirectURLStr, http.StatusFound)
// The log middleware can capture the OIDC user login event with the URL, but it cannot get the current username from security context because the security context is not ready yet.
// need to create login event in the OIDC login call back logic
// to avoid generate duplicate event in audit log ext, the PreCheck function of the login event intentionally bypass the OIDC user login event in log middleware
// and OIDC's login callback function will create the login event and send it to notification.
if config.AuditLogEventEnabled(ctx, loginUserOperation) {
e := &commonevent.Metadata{
Ctx: ctx,
Username: u.Username,
RequestMethod: oc.Ctx.Request.Method,
RequestURL: oc.Ctx.Request.URL.String(),
}
notification.AddEvent(e.Ctx, e, true)
}
}
func userOnboard(ctx context.Context, oc *OIDCController, info *oidc.UserInfo, username string, tokenBytes []byte) (*models.User, bool) {

View File

@ -33,6 +33,7 @@ func init() {
var login = &loginResolver{}
var logout = &logoutResolver{}
commonevent.RegisterResolver(`/c/login$`, login)
commonevent.RegisterResolver(`/c/oidc/callback.*`, login)
commonevent.RegisterResolver(`/c/log_out$`, logout)
}
@ -54,7 +55,7 @@ func (l *loginResolver) Resolve(ce *commonevent.Metadata, event *event.Event) er
OcurrAt: time.Now(),
Operation: opLogin,
OperationDescription: opLogin,
IsSuccessful: true,
IsSuccessful: ce.ResponseCode <= http.StatusTemporaryRedirect,
}
// Extract the username from payload
@ -65,9 +66,10 @@ func (l *loginResolver) Resolve(ce *commonevent.Metadata, event *event.Event) er
e.ResourceName = match[1]
e.Operator = match[1]
}
}
if ce.ResponseCode != http.StatusOK {
e.IsSuccessful = false
} else if ce.RequestMethod == http.MethodGet {
e.IsSuccessful = true // for OIDC login event, always success
e.Operator = ce.Username
e.ResourceName = ce.Username
}
event.Topic = ctlevent.TopicCommonEvent
event.Data = e