I just read a good article by Bryan Rite about the security principles involved in preventing dictionary attacks. He makes a good point about offloading the work to a service like OpenID if possible, and has some other tips to use if you have to implement it yourself. Some of it challenges the conventional wisdom, but I think he does a good job of defending his position.