Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

SEC-984: CasAuthenticationProvider cannot authenticate on custom attributes #1236

spring-issuemaster opened this Issue Sep 21, 2008 · 7 comments


None yet
1 participant

Henrik Kragh-Hansen(Migrated from SEC-984) said:

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.

Luke Taylor said:

The UserDetailsService interface is used throughout the framework and can’t be changed as it is one of the most common customization points – to do so would break.

I’ve discussed it with Scott and we’ve agreed that extracting a template method would allow you to extend the provider with minimal overhead. So something like

protected UserDetails loadUserDetails(Assertion assertion) {
return userDetailsService.loaduserDetails(assertion.getPrincipal().getName());

as the default implementation.

Scott Battaglia said:

Added template method and appropriate javadoc. Name differs slightly from the one described in here:

     \* Template method for retrieving the UserDetails based on the assertion.  Default is to call configured userDetailsService and pass the username.  Deployers
     \* can override this method and retrieve the user based on any criteria they desire.
     \* @param assertion The CAS Assertion.
     \* @returns the UserDetails.
    protected UserDetails loadUserByAssertion(final Assertion assertion) {
        return this.userDetailsService.loadUserByUsername(assertion.getPrincipal().getName());

Luke, I changed this to 2.0.4 since its done.

Henrik Kragh-Hansen said:

I have downloaded version 2.0.4 of spring security, and I have not been able to locate any method corresponding to the changes described here.

The CasAuthenticationProvider class still contains the method:

private CasAuthenticationToken authenticateNow(Authentication authentication) throws AuthenticationException {
try {
final Assertion assertion = this.ticketValidator.validate(authentication.getCredentials().toString(), serviceProperties.getService());
final UserDetails userDetails = userDetailsService.loadUserByUsername(assertion.getPrincipal().getName());

Here the .loadUserByUsername is still invoked directly.
I might have missunderstood how you have corrected this problem.

I have tried downloading 2.0.4 through maven and directly from your homepage and I cant locate the correction anywhere.

Scott Battaglia said:

Click on the FishEye link in JIRA, the change appears there.


Henrik Kragh-Hansen said:

Well the changes in the FishEye view is very nice, and they solve my problems, but my problem is that the version of the implementation in the 2.0.4 jar of spring security is:

@version $Id: CasAuthenticationProvider.java 2710 2008-03-10 18:33:34Z sbattaglia $

where the changes should be in:

@version $Id: CasAuthenticationProvider.java 3284 2008-10-01 18:49:52Z sbattaglia $

The 2.0.4 version is from 2008-10-02 so I dont know why this change is not available in the 2.0.4 release.
As stated in my previous post I have tried to download 2.0.4 from your homepage and through maven, and both does not contain the

protected UserDetails loadUserByAssertion(final Assertion assertion)

method, and I have also checked the source, which appears to be the old version.

Regards Henrik

Scott Battaglia said:

I don’t do the builds so I can’t speak for why it didn’t make it in unless someone didn’t check out correctly before doing the build. Maybe Luke will see this and know why.

Luke Taylor said:

Hi guys,

2.0.4 was scheduled for the 12th September and was tagged before that:


Thats the tag the build team used, so nothing that’s been done in trunk since then will be included. We use the maven release plugin, so there should never be any issues with failing to do a proper checkout for a release.

I’ve changed the fix version back to 2.5

@spring-issuemaster spring-issuemaster added this to the 3.0.0 M1 milestone Feb 5, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment