that is true!  I tried PrincipalIdAttribute, the flow made no difference.

But the problem remains.  say user johnsmith in CAS maps to  jsmith in 
Okta.  I can do some validation so that when Okta authenticates jsmith, CAS 
returns principal as johnsmith, I still want CAS to store johnsmith 
somewhere Before it delegates to Okta.  (It is possible multiple users in 
CAS maps to the same Okta user, thus we want to know the username entered 
in CAS -before- delegating to Okta).  This is similar to how CAS handles 
relay_state in SAML delegated authN. 

this following is my idea, but did not work.

public class MyDelegatedClientAuthenticationWebflowStateContributor extends 
DefaultDelegatedClientAuthenticationWebflowStateContributor {
    @Override
    public Map<String, Serializable> store(final RequestContext 
requestContext, final WebContext webContext,
                                           final Client client) throws 
Throwable {
// user enters username: johnsmith in CAS UI, CAS looks up external IdP, it 
is Okta.
// we store username johnsmith before delegated authN
// but I do not know how to get the username that user entered earlier in 
CAS UI
        String userBeforeDelegateAuthN = (String) ..... ??
        Map<String, Serializable> properties = new 
HashMap<>(super.store(requestContext, webContext, client));
        properties.put("userBeforeDelegateAuthN", userBeforeDelegateAuthN);
        return properties;
    }
    
    @Override
    public Service restore(final RequestContext requestContext,
                           final WebContext webContext,
                           final Optional<TransientSessionTicket> 
givenSessionTicket,
                           final Client client) {   
        val service = super.restore(requestContext, webContext, 
givenSessionTicket, client);  
        val properties = givenSessionTicket.get().getProperties();
// we put username back into request attribute as SAML response comes from 
Okta
// then, somewhere else (such as authenticationHandler),  I get this 
attribute, create the principal using this attribute:  johnsmith (CAS 
username), 
         // copying Okta attributes for jsmith
        webContext.setRequestAttribute("userBeforeDelegateAuthN", 
properties.get("userBeforeDelegateAuthN"));
        return service;
    }    
}


On Monday, October 6, 2025 at 2:23:03 PM UTC-4 Ray Bon wrote:

> Do you control the data in the remote IdP?
> If you do not control the remote data, how do you guarantee that the 
> username returned is unique and not modifiable by the user?
> What would happen if the user entered a different username, johns, instead?
> If you just store the username as part of the login flow, any user with an 
> Okta account could log in as one of your users.
>
> You need to establish the remote / local relationship before the user logs 
> in; then look up the local user with the remote username from Okta.
>
> There is this property to get the remote  username [1]:
> Cas.authn.pac4j.saml[0].name-id-attribute 
>
>
> Ray
>
> [1] 
> https://apereo.github.io/cas/7.2.x/integration/Delegate-Authentication-SAML2.html
> ------------------------------
> *From:* [email protected] <[email protected]> on behalf of Yan Zhou <
> [email protected]>
> *Sent:* October 6, 2025 07:13
> *To:* CAS Community <[email protected]>
> *Subject:* [cas-user] store-for-match-later in delegated authN 
>  
> Hello, 
>
> CAS 7.2, delegated AuthN with SAML. In CAS screen where you enter username 
> in order for CAS to locate the external IdP, the business problem I deal 
> with is that the username in CAS is Different from that is in External 
> IdP.  For instance, I may enter username: johnsmith in CAS, it goes to 
> Okta, but in Okta, user may enter their Okta username: jsmith. When SAML 
> response comes back to CAS, I want CAS create a principal with the CAS 
> username johnsmith (Not jsmith as Okta says), and with attributes from Okta 
> jsmith user.  There is one level of indirection here.
>
> How and where do I store the CAS username before CAS delegates to external 
> Idp, and match it with response later on?  The outbound delegation and 
> inbound response are two different requests.
>
> thx!
>
> -- 
> - Website: https://apereo.github.io/cas
> - List Guidelines: https://goo.gl/1VRrw7
> - Contributions: https://goo.gl/mh7qDG
> --- 
> You received this message because you are subscribed to the Google Groups 
> "CAS Community" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion visit 
> https://groups.google.com/a/apereo.org/d/msgid/cas-user/fc344419-f41a-4b54-8ed9-84cc3e6649e0n%40apereo.org
>  
> <https://groups.google.com/a/apereo.org/d/msgid/cas-user/fc344419-f41a-4b54-8ed9-84cc3e6649e0n%40apereo.org?utm_medium=email&utm_source=footer>
> .
>

-- 
- Website: https://apereo.github.io/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
--- 
You received this message because you are subscribed to the Google Groups "CAS 
Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/a/apereo.org/d/msgid/cas-user/8654f9bf-a653-4ed5-ab80-a692622a8422n%40apereo.org.

Reply via email to