David, Thanks for sharing this. We've been mulling over a similar extension to Shib IdPv2. Since primary authN, whether that be front- or back-channel, is really independent of the particular WebSSO protocol in use, it seems like a real win to be able to leverage authN methods of other frameworks/products (Shiro, Spring,...).
Best, Bill On Fri, Jun 7, 2013 at 7:36 PM, Ohsie, David <[email protected]> wrote: > I recently had a need for password hashing in a project where I was using > CAS. In this case, it was hashing to a password from a jdbc datasource. > > > > Rather than adding specific classes or extensions to the cas jdbc > authenticator classes, I simply used spring security classes to do the > authentication. Spring security already has support for salt sources in the > passsword field as well as outside salt sources. > > > > I wrote a simple adapter (not yet for production) to enable a Spring > AuthenticationManager to be used as a CAS AuthenticationHandler supporting > UsernamePasswordCredentials only. So I was able to get what I needed in > about 50 lines of code, but I opened up a whole set of features from spring > security (code attached below along with configuration example). > > > > In general, there seems to be a lot of duplication of concept and function > between the cas authenticators, persondir and spring security (and probably > shiro). I think that the the right approach may be a set of adapters from > cas to spring security or shiro that would enable many features and remove > the need for additional CAS code to supply these. > > > > David Ohsie > > Software Architect > > EMC Corporation > > > > <property name="authenticationHandlers"> > > <list> > > <bean id="localUserAuthHandler" > class="com.emc.shared.security.cas.spring.UsernamePasswordAuthenticationHandler"> > > <property name="authenticationManager"> > > <bean > class="org.springframework.security.authentication.ProviderManager"> > > <constructor-arg> > > <list> > > <bean > class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> > > <property name="passwordEncoder"> > > <bean > class="org.springframework.security.crypto.password.StandardPasswordEncoder"/> > > </property> > > <property name="userDetailsService"> > > <bean > class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> > > <property name="enableAuthorities" value="true"/> > > <property name="enableGroups" value="false"/> > > <property name="usersByUsernameQuery" value="select > username, password, TRUE as enabled from users where username = ?"/> > > <property name="authoritiesByUsernameQuery" > value="select ? as username, 'dummy' as authority"/> > > <property name="dataSource" > ref="localUserDataSource"/> > > </bean> > > </property> > > </bean> > > </list> > > </constructor-arg> > > </bean> > > </property> > > </bean> > > </list> > > </property> > > > > package com.emc.shared.security.cas.spring; > > > > import org.jasig.cas.authentication.principal.Credentials; > > import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; > > import org.jasig.cas.authentication.handler.AuthenticationHandler; > > import org.jasig.cas.authentication.handler.AuthenticationException; > > > > import org.springframework.security.authentication.AuthenticationManager; > > import > org.springframework.security.authentication.UsernamePasswordAuthenticationToken; > > > > import org.springframework.security.crypto.password.StandardPasswordEncoder; > > > > import org.slf4j.Logger; > > import org.slf4j.LoggerFactory; > > > > class UsernamePasswordAuthenticationHandler implements AuthenticationHandler > > { > > final private Logger logger_ = > LoggerFactory.getLogger(UsernamePasswordAuthenticationHandler.class); > > private AuthenticationManager authManager_; > > > > public static void main(String [] args) > > { > > StandardPasswordEncoder encoder = new StandardPasswordEncoder(); > > System.out.println(encoder.encode(args[0])); > > } > > > > public void setAuthenticationManager(AuthenticationManager am) > > { > > authManager_ = am; > > } > > > > public AuthenticationManager getAuthenticationManager() > > { > > return authManager_; > > } > > > > public boolean supports(final Credentials credentials) > > { > > return credentials != null > > && > UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass()); > > } > > > > public boolean authenticate(Credentials credentials) throws > AuthenticationException > > { > > try { > > UsernamePasswordCredentials upCredentials = > (UsernamePasswordCredentials) credentials; > > UsernamePasswordAuthenticationToken upToken = > > new > UsernamePasswordAuthenticationToken(upCredentials.getUsername(), > upCredentials.getPassword()); > > authManager_.authenticate(upToken); > > upToken.eraseCredentials(); > > return true; > > } > > catch (Exception ex) > > { > > logger_.info(ex.toString()); > > return false; > > } > > } > > } > > > > > > From: Andrew Petro [mailto:[email protected]] > Sent: Friday, June 07, 2013 12:08 PM > To: [email protected] > Subject: Re: [cas-dev] Support for Salted Passwords in CAS4? > > > > Seems like a feature that can be deferred, affording time and experience to > shake out the design in a feature branch or forked repo or extension module > before drawing it in stable and baked to a future CAS release, no? > > > > I agree support for salting has promise; I'm having trouble seeing now as a > good moment to go after this in cas-server itself. > > > > cas-addons has some salting support. It's not baked enough (static salt is > not sufficient) and so I don't suggest drawing that into cas-server itself > at this time. Were it more successfully baked, I'd be suggesting that. > > > > https://github.com/Unicon/cas-addons/blob/master/src/main/java/net/unicon/cas/addons/authentication/handler/ShiroHashServicePasswordEncoder.java > > > > Perhaps the next thing to do to that code is to enable dynamic salt (i.e., > the username) rather than a static salt. > > > > Andrew > > > > > > On Fri, Jun 7, 2013 at 5:46 AM, Marvin S. Addison <[email protected]> > wrote: > > Salted passwords have come up on cas-user a number of times over the past > several years and it seems like now is a good time to consider adding > support in the scope of authn API changes. Unfortunately there are few > standards for salted hashing where the authentication pipeline would need to > perform the encoding. For quasi standards like OpenLDAP SSHA [1], for > example, the cleartext password is provided on a simple bind and the > encoding happens server side. > > Beyond the standards problem, there is the matter of following best > practices where each password is salted with a unique value. Some systems > generate random salts and store them, others derive the salt from an > attribute of the user account record (e.g. taking some bytes from the hashed > account creation time). From a design perspective we would need a strategy > pattern that allowed a fair bit of flexibility to accommodate variable salt > values. The high variance and absence of standards pretty much guarantees > that we can't provide anything out of the box. It also makes it difficult to > design the inputs into the strategy, but the following would support both > cases I mentioned assuming there would be a lookup on username to get the > (derived) salt: > > interface PasswordSaltStrategy { > byte[] lookup(UsernamePasswordCredential credential); > } > > Unfortunately there's an additional complication of how the salt is joined > with the password in computing the hash. Some methods prepend the salt and > others append it; there may be other approaches. > > With all the variation and lack of standards this looks difficult. Are there > any concrete requirements to drive this feature? I recall general requests > for "salted passwords," but I can't find any specific requests or citations > of standards. > > M > > [1] http://www.openldap.org/faq/data/cache/347.html > > -- > You are currently subscribed to [email protected] as: > [email protected] > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev > > > > -- > You are currently subscribed to [email protected] as: > [email protected] > > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev -- You are currently subscribed to [email protected] as: [email protected] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev
