Skip to content

Commit faaece1

Browse files
committed
feat: add adfs fallback to match upn or unique_name
1 parent 606ef60 commit faaece1

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

wavefront/server/modules/user_management_module/user_management_module/controllers/auth_plugin_controller.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
from authenticator import AuthenticatorType
3636
from authenticator.helper import validate_email
37+
from authenticator.microsoft_adfs import MicrosoftADFSAuthenticator
3738

3839

3940
auth_plugin_router = APIRouter()
@@ -573,6 +574,28 @@ def get_failure_redirect(error_msg: str) -> RedirectResponse:
573574
user = await user_repository.find_one(email=ui.email)
574575
if user is None and ui.email:
575576
user = await user_repository.find_one(username=ui.email.lower())
577+
578+
# ADFS fallback: when the email lookup fails (even though an email was
579+
# present in the id_token), retry using the upn and unique_name claims.
580+
# These claims carry raw values like ``DOMAIN\userid`` or
581+
# ``userid@domain``; the stored username is just the bare id, so the
582+
# identifier must be extracted from the claim before matching.
583+
if user is None and isinstance(authenticator, MicrosoftADFSAuthenticator):
584+
for candidate in (ui.upn, ui.unique_name):
585+
identifier = authenticator.extract_identifier_from_claim(candidate)
586+
if not identifier:
587+
continue
588+
identifier = identifier.lower()
589+
user = await user_repository.find_one(username=identifier)
590+
if user is not None:
591+
logger.debug(
592+
'_handle_oauth_callback: ADFS fallback matched user via '
593+
'claim=%s identifier=%s',
594+
candidate,
595+
identifier,
596+
)
597+
break
598+
576599
logger.debug(
577600
'_handle_oauth_callback: user lookup by identifier=%s found=%s deleted=%s',
578601
ui.email,

wavefront/server/plugins/authenticator/authenticator/microsoft_adfs/authenticator.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,17 @@ def _exchange_code_for_token(
333333
None,
334334
)
335335

336+
def extract_identifier_from_claim(self, value: Optional[str]) -> Optional[str]:
337+
"""Public wrapper around identifier extraction for upn/unique_name claims.
338+
339+
Lets callers (e.g. the auth controller) resolve the bare user id stored
340+
as a username from a raw ``upn``/``unique_name`` claim value such as
341+
``DOMAIN\\userid`` or ``userid@domain``.
342+
"""
343+
if not value:
344+
return None
345+
return self._extract_identifier_from_claim(value)
346+
336347
def _extract_identifier_from_claim(self, value: str) -> Optional[str]:
337348
"""Pull the user identifier out of a raw UPN or unique_name string.
338349

0 commit comments

Comments
 (0)