enhancement
major
minor
defect
critical
major
minor
major
#30108
pac4j Registration: The account mapping receives the identity provider's full identity (subject, claims) rather than just a login name
Context
Pac4jAuthenticationServlet.getLoginCredentials (com.top_logic.security.auth.pac4j) reduces a successful login to the identity provider to a string:
String userName = getUserName(profile, clientName); // UserNameExtractor -> String ExternalUserMapping userMapping = Pac4jConfigFactory.getInstance().getUserMapping(clientName); return LoginCredentials.fromUser(userMapping.findAccountForExternalName(userName));
ExternalUserMapping.findAccountForExternalName(String) (tl-core) only sees this name. The existing implementations look up the user using `Person.byName`. The identity provider’s subject (`profile.getId()`; for OpenID Connect, the `sub` claim) and the other claims (`email`, `email_verified`, …) are not passed during the mapping process.
Therefore, an application cannot map an account using the identity provider’s stable identifier. It also cannot create or link an account during the first login if more than one value is required for that purpose. Example: Tax Application (tl-factory, Issue 2): An administrator invites a member using an email address. Upon first login, the account should be found using the verified email address from the invitation and then permanently mapped via `sub`, never via the display name.
Related: #22471 (Federating accounts via OpenID) and #26452 (Simpler registration for logging in via OpenID). This ticket addresses the small, general part that both require: the mapping interface.
Solution
- ExternalUserMapping will gain a method that receives the entire authenticated identity: client name, subject, the extracted name, and the claims (e.g., an immutable value type ExternalIdentity). The default implementation calls ` findAccountForExternalName(name) `. Existing mappings will therefore remain unchanged.
- Pac4jAuthenticationServlet passes the profile via this method.
- An application can find an account in its mapping using the Subject, or create or link it in its own transaction. If neither applies, it throws an `UnknownAccountException`, and the existing page for unknown accounts appears.
- Test: An association receives the subject and claims from a login; the default implementation returns the same account as before.