add authenticate events

This commit is contained in:
Denis Mishin 2023-04-25 17:10:46 -04:00
parent 3d9322bd32
commit dda4a878bc
4 changed files with 63 additions and 3 deletions

View file

@ -216,6 +216,8 @@ func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) error {
a.cfg.profileTrimFn(profile)
}
a.logAuthenticateEvent(r, profile)
redirectTo, err := urlutil.CallbackURL(state.hpkePrivateKey, proxyPublicKey, requestParams, profile)
if err != nil {
return httputil.NewError(http.StatusInternalServerError, err)
@ -315,6 +317,8 @@ func (a *Authenticate) reauthenticateOrFail(w http.ResponseWriter, r *http.Reque
return err
}
a.logAuthenticateEvent(r, nil)
state.sessionStore.ClearSession(w, r)
redirectURL := state.redirectURL.ResolveReference(r.URL)
nonce := csrf.Token(r)

View file

@ -2,10 +2,14 @@ package authenticate
import (
"net/http"
"net/url"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/middleware"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/grpc/identity"
"github.com/pomerium/pomerium/pkg/hpke"
)
// requireValidSignatureOnRedirect validates the pomerium_signature if a redirect_uri or pomerium_signature
@ -48,3 +52,40 @@ func (a *Authenticate) getExternalRequest(r *http.Request) *http.Request {
return urlutil.GetExternalRequest(internalURL, externalURL, r)
}
func (a *Authenticate) logAuthenticateEvent(r *http.Request, profile *identity.Profile) {
state := a.state.Load()
ctx := r.Context()
pub, params, err := hpke.DecryptURLValues(state.hpkePrivateKey, r.Form)
if err != nil {
log.Warn(ctx).Err(err).Msg("log authenticate event: failed to decrypt request params")
}
evt := log.Info(ctx).
Str("pomerium_version", params.Get(urlutil.QueryVersion)).
Str("pomerium_request_uuid", params.Get(urlutil.QueryRequestUUID)).
Str("pomerium_pub", pub.String())
if uid := getUserID(profile); uid != "" {
evt = evt.Str("authenticate_event", "sign_in_completed").
Str("pomerium_idp_user", getUserID(profile))
} else {
evt = evt.Str("authenticate_event", "sign_in")
}
if redirectURL, err := url.Parse(params.Get(urlutil.QueryRedirectURI)); err == nil {
evt = evt.Str("domain", redirectURL.Hostname())
}
evt.Msg("authenticate: event")
}
func getUserID(profile *identity.Profile) string {
if profile == nil {
return ""
}
if profile.Claims == nil {
return ""
}
return profile.Claims.Fields["sub"].GetStringValue()
}

View file

@ -4,8 +4,12 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"runtime"
"strings"
"time"
"github.com/google/uuid"
"google.golang.org/protobuf/encoding/protojson"
"github.com/pomerium/pomerium/internal/version"
@ -21,6 +25,15 @@ const DefaultDeviceType = "any"
const signInExpiry = time.Minute * 5
var (
pomeriumRuntime = os.Getenv("POMERIUM_RUNTIME")
pomeriumArch = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
)
func versionStr() string {
return strings.Join([]string{version.FullVersion(), pomeriumArch, pomeriumRuntime}, " ")
}
// CallbackURL builds the callback URL using an HPKE encrypted query string.
func CallbackURL(
authenticatePrivateKey *hpke.PrivateKey,
@ -59,7 +72,7 @@ func CallbackURL(
return "", fmt.Errorf("error marshaling identity profile: %w", err)
}
callbackParams.Set(QueryIdentityProfile, string(rawProfile))
callbackParams.Set(QueryVersion, version.FullVersion())
callbackParams.Set(QueryVersion, versionStr())
BuildTimeParameters(callbackParams, signInExpiry)
@ -99,7 +112,8 @@ func SignInURL(
q := signInURL.Query()
q.Set(QueryRedirectURI, redirectURL.String())
q.Set(QueryIdentityProviderID, idpID)
q.Set(QueryVersion, version.FullVersion())
q.Set(QueryVersion, versionStr())
q.Set(QueryRequestUUID, uuid.NewString())
BuildTimeParameters(q, signInExpiry)
q, err := hpke.EncryptURLValues(senderPrivateKey, authenticatePublicKey, q)
if err != nil {
@ -119,7 +133,7 @@ func SignOutURL(r *http.Request, authenticateURL *url.URL, key []byte) string {
if redirectURI, ok := RedirectURL(r); ok {
q.Set(QueryRedirectURI, redirectURI)
}
q.Set(QueryVersion, version.FullVersion())
q.Set(QueryVersion, versionStr())
u.RawQuery = q.Encode()
return NewSignedURL(key, u).Sign().String()
}

View file

@ -19,6 +19,7 @@ const (
QuerySessionEncrypted = "pomerium_session_encrypted"
QuerySessionState = "pomerium_session_state"
QueryVersion = "pomerium_version"
QueryRequestUUID = "pomerium_request_uuid"
)
// URL signature based query params used for verifying the authenticity of a URL.