/* ==================================================================
* DelegatingPasswordEncoder.java - Mar 19, 2013 9:37:08 AM
*
* Copyright 2007-2013 SolarNetwork.net Dev Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ==================================================================
*/
package net.solarnetwork.central.security;
import java.util.Map;
/**
* Password encoder that delegates to a configurable list of Spring Security
* {@code org.springframework.security.crypto.password.PasswordEncoder}
* instances, returning passwords with a prefix tag to be able to recognize what
* encryption technique was used.
*
* <p>
* The configurable properties of this class are:
* </p>
*
* <dl class="class-properties">
* <dt>encoders</dt>
* <dd>An ordered Map of password prefix tag keys to associated
* <code>PasswordEncoder</code> instances. The first entry in the map according
* to iteration order will be used as the primary encoder. Thus a map
* implementation like {@link java.util.LinkedHashMap} is recommended.</dd>
* </dl>
*
* @author matt
* @version 1.0
*/
public class DelegatingPasswordEncoder implements PasswordEncoder,
org.springframework.security.crypto.password.PasswordEncoder {
private Map<String, org.springframework.security.crypto.password.PasswordEncoder> encoders;
@Override
public boolean isPasswordEncrypted(CharSequence password) {
if ( encoders == null || password == null ) {
return false;
}
for ( String prefix : encoders.keySet() ) {
if ( password.length() > prefix.length()
&& password.subSequence(0, prefix.length()).equals(prefix) ) {
return true;
}
}
return false;
}
@Override
public String encode(CharSequence rawPassword) {
if ( encoders == null || encoders.size() < 1 ) {
throw new RuntimeException("No password encoders configured");
}
Map.Entry<String, org.springframework.security.crypto.password.PasswordEncoder> entry = encoders
.entrySet().iterator().next();
return entry.getValue().encode(rawPassword);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if ( encodedPassword == null || rawPassword == null ) {
return false;
}
for ( Map.Entry<String, org.springframework.security.crypto.password.PasswordEncoder> entry : encoders
.entrySet() ) {
String prefixTag = entry.getKey();
if ( encodedPassword.startsWith(prefixTag) ) {
return entry.getValue().matches(rawPassword, encodedPassword);
}
}
return false;
}
public void setEncoders(
Map<String, org.springframework.security.crypto.password.PasswordEncoder> encoders) {
this.encoders = encoders;
}
}