I have this system where users need to signin using an existing CAS. The response from the CAS is the username and a lot of additional attributes. I need one of these attributes in order to get the information in need to create a UserDetails object, because the information is retrieved from another webservice, where one of the custom attributes is the key, instead of the username.
When authentication is performed in CasAuthenticationProvider and the method authenticateNow(Authentication authentication) is invoked, it initially validates the ticket using the supplied ticket validator.
I have written my own custom validator which extends from Cas20ServiceTicketValidator, and then made an override implementation of customParseResponse(final String response, final Assertion assertion), where I parse the responce and add additional attributes to the assertion map.
My problem occurs when the UserDetails should be retrieved from the UserDetailsService, when userDetailsService.loadUserByUsername(assertion.getPrincipal().getName()) is invoked. In order to retrieve the information needed to create a UserDetails object, I need the custom attributes, which i retrieved through my custom validator, but this information is not parsed to the loadUserByUsername method.
My current solution to this problem is to make my own implementation of CasAuthenticationProvider. Which does not use the UserDetailsService interface but instead my own, where i can pass my attributes together with the username.
A solution to this problem could be to add the following method to the UserDetailsService interface:
UserDetails loadUserByUsername(String username, Assertion assertion) throws UsernameNotFoundException, DataAccessException;
Where the Assertion is the response from ticketValidator.validate(authentication.getCredentials().toString(), serviceProperties.getService());
It is then possible to create the UserDetails based on both the username and custom attributes.