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.UsernamePasswordAuthenticationHand
ler">

          <property name="authenticationManager">

            <bean
class="org.springframework.security.authentication.ProviderManager">

              <constructor-arg>

                <list>

                  <bean
class="org.springframework.security.authentication.dao.DaoAuthenticationProv
ider">

                    <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.UsernamePasswordAuthenticationTo
ken;

 

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/ca
s/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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to