Apr 17th, 2007, 03:58 PM
I am using Acegi 1.0.3 with CAS 3.0.6.
I have read some of the other threads that talk about handling expiration of credentials.
There is an attribute User.credentialsNonExpired that I would want to use. However, the built in functionality does not ever populate credentialsNonExpired to false. The standard JdbcDaoImpl.UsersByUsernameMapping.mapRow() always populates the User attribute as true. To enable this functionality, I assumed that I should extend the JdbcDaoImpl and write my own UsersByUsernameMapping. This I did, however, as is stated in the threads I referenced above, JdbcDaoImpl.loadUserByUsername() creates a new User object setting the credentialsNonExpired value to true.
So I override the loadUserByUsername() method to return a User object that sets User.credentialsNonExpired to the appropriate value. It is after this point that I need some help.
AbstractUserDetailsAuthenticationProvider.authenti cate() is where we end up with User.credentialsNonExpired = false. This authenticate() method will throw a CredentialsExpiredException which is caught by ProviderManager.doAuthentication(). After this the end user is sent back the login page informing them that the credentials are invalid.
I would expect that the end user would be instead directed to a change password screen that would force them to create a new password. How does a non-CASified Acegi behave under this circumstance? Does it also send the end user back to the login page? What is the recommended code changes/overrides to implement redirection to a change password screen?
My first instinct is to override AbstractUserDetailsAuthenticationProvider.authenti cate() so that is does not throw an exception when User.credentialsNonExpired = false. This will allow the end user to log in. Then I would add a servlet filter that reads the User object for this field and redirects appropriately.
Does that sound reasonable? Has anyone tackled this problem before? My only issue with the solution I'm thinking of is that I end up overriding more than I expected for what I assumed was built in to Acegi. I acknowledge that Acegi can't be everything to everyone, but I think this is fairly standard functionality that any security conscious web site should have implemented.
Apr 18th, 2007, 10:47 AM
On further reflection, I have decided to build this credential expiration handling differently than previously stated. I'll detail it here if anyone is at all interested.
I have a class MyJdbcDaoImpl that extends JdbcDaoImpl which contains the inner classes that query from the DEF_USERS_BY_USERNAME_QUERY and DEF_AUTHORITIES_BY_USERNAME_QUERY resultsets. This will populate credentialsNonExpired according to my business rules. This class is used in my CAS server.
I have a second class MyClientJdbcDaoImpl which extends MyJdbcDaoImpl . It overrides the method loadUserByUsername() to construct the User object as:
return new User(returnUsername, user.getPassword(), user.isEnabled(), true, user.isCredentialsNonExpired(), true, arrayAuths);
This class is used in each of my CAS clients.
Lastly, I have the servlet filter that i mentioned in my previous post to check User.credentialsNonExpired and redirect to the change password view if necessary. This servlet filter is added to each of the CAS clients filterChainProxy.
May 28th, 2009, 05:21 AM
spring security password change
i am interested in redirecting user to change password page if user credentials are expired.
right now in my scenario i fetch user info from DB ,and create a AuthenticatedUserDto which extends user .like:-
authenticatedUserInfo = new AuthenticatedUserDto(userInfo.getUserName(),
userInfo.getPassword(),activeOrInactive,true, credentialsStatus, true,userAuthority,"",userInfo.getEmpId());