fix: emit FAILED_LOGIN audit event when Basic Auth rejects credentials in multi-auth (SAML + Basic) setup#6285
Conversation
…s in multi-auth (SAML + Basic) setup Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
|
@mvanhorn Can you run |
| SAML and basic auth for example redirect/re-request credentials from clients. | ||
| */ | ||
| authCredentials = ac; | ||
| if (ac != null) { |
There was a problem hiding this comment.
I see why this is being done since extractCredentials from HTTPSamlAuthenticator will return null when doing basic auth, but it does feel hacky. I think this really illustrates that the reRequestAuthentication flow is not structured well. Because of the design, we require challenge: true for authenticators like the SAML authenticator when challenge really only makes sense for HTTP Basic auth.
Can we add a comment in here explaining the rationale?
DarshitChanpura
left a comment
There was a problem hiding this comment.
thank you @mvanhorn for this improvment!
| if (authenticatorType.equals(BASIC_TYPE)) { | ||
| log.warn("No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'"); | ||
| } | ||
| notifyIpAuthFailureListeners(request, authCredentials); |
There was a problem hiding this comment.
since authCredentials now retains the rejected username across iterations, notifyIpAuthFailureListeners call here will also receive the actual username instead of null when firing from the SAML challenge path which may end up improving failed login tracking by attributing user (if available) to an IP.
| SAML and basic auth for example redirect/re-request credentials from clients. | ||
| */ | ||
| authCredentials = ac; | ||
| if (ac != null) { |
Description
challenge: falseat order 1, SAML withchallenge: truelater), a failed Basic Auth login through the Dashboards login form produced no FAILED_LOGIN audit event, so brute-force attempts were invisible to audit logs. The suppression added by Remove failed login attempt for saml authenticator #4762 (to silence false positives during normal SAML redirects) also fires when Basic Auth has already rejected real credentials, because the loop overwrites the previously extracted credentials with null in the SAML iteration and then returns from the suppressed branch without logging.BackendRegistry.authenticatepreserves the last extracted credentials across auth-domain iterations (authCredentialsis only overwritten when the new extraction is non-null), and the Remove failed login attempt for saml authenticator #4762 suppression is narrowed to apply only when no earlier domain rejected real credentials. A genuine failed Basic login now emits FAILED_LOGIN with the rejected username; an unauthenticated browser hitting the SAML redirect still logs nothing, preserving the [BUG] Audit Log publish Incorrect FAILED_LOGIN event for Successful login attempt by SAML user on SAML enabled Domain #4608 fix.Issues Resolved
Fixes #6221
Is this a backport? No.
Do these changes introduce new permission(s) to be displayed in the static dropdown on the front-end? No.
Testing
New
BackendRegistryTestfollows the existingBackendRegistryGrpcAuthTestpattern (mockedAdminDNs/XFFResolver/AuditLog/ThreadPool/ClusterInfoHolder, auth domains injected via a mockedDynamicConfigModel). Covers: rejected Basic credentials followed by a SAML challenge emits FAILED_LOGIN with the rejected username; a bare SAML redirect with no extracted credentials stays silent (the #4608 behavior); single-domain Basic rejection still logs as before.Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.