jquery

gist JS

Wednesday, September 19, 2007

Re: You're Probably Storing Passwords Incorrectly

As always the problem with best practices is that you often hear about them after you've gone and implemented something less ideal.

CodingHorror's post was pretty good at guilting me into salting passwords
http://www.codinghorror.com/blog/archives/000953.html
I knew this would be easy with Acegi and of course it was a breeze...

Except for that little problem about existing users who would still like to log in.

Clearly salting passwords is a decision you'd prefer to make BEFORE you've hashed a whole bunch of passwords. As tempting as it is to rainbow attack your own passwords and then convert them to salted versions (which wouldn't work anyway) and without making everyone reset their passwords you're left a bit in the lurch. But never fear, TransitionReflectionSaltSource is here! (Second choice after 'doh!ReflectionSaltSource')

This class allows you to transition to using salt in an AcegiSecurity system. New users get salt, old users still work. You pick the date field and time to start applying salt. This class will salt users from after the useSaltAfterDate. Null useSaltAfterDate will not be salted. You could easily change this to some other User property.

/**
*
* @author Jeff Dwyer (blog) http://jdwyah.blogspot.com
*
*/
public class TransitionReflectionSaltSource extends ReflectionSaltSource {
private static final Logger log = Logger.getLoggerTransitionReflectionSaltSource.class);

private String useSaltAfterDateProperty;
private Date useSaltAfterDate;

@Override
public Object getSalt(UserDetails user) {
try {
Method reflectionMethod = user.getClass().getMethod(this.useSaltAfterDateProperty,
new Class[] {});
Date userDate = (Date) reflectionMethod.invoke(user, new Object[] {});
if (null == userDate userDate.before(useSaltAfterDate)) {
log.debug("No Salt " + user + " " + userDate);
return null;
} else {
log.debug("Using Salt " + user + " " + userDate);
return super.getSalt(user);
}
} catch (Exception exception) {
throw new AuthenticationServiceException(exception.getMessage(), exception);
}
}
@Required
public void setUseSaltAfterDateProperty(String useSaltAfterDateProperty) {
this.useSaltAfterDateProperty = useSaltAfterDateProperty;
}

@Required
public void setUseSaltAfterDate(Date useSaltAfterDate) {
this.useSaltAfterDate = useSaltAfterDate;
}
}



Now we setup our TransitionalReflectionSaltSource to only salt things created after today, (the day we got guilted into fixing this)

<bean id="userSaltSource" class="com.aavu.server.util.TransitionReflectionSaltSource">
<property name="userPropertyToUse" value="getId" />
<property name="useSaltAfterDateProperty" value="getDateCreated" />
<property name="useSaltAfterDate">
<bean class="java.util.Date">
<constructor-arg>
<value>107</value>
</constructor-arg>
<constructor-arg>
<value>8</value>
</constructor-arg>
<constructor-arg>
<value>18</value>
</constructor-arg>
</bean>
</property>
</bean>


Easy! Is there a better way to inject a date though?