diff options
Diffstat (limited to 'eaaf-springboot-utils/src/main')
| -rw-r--r-- | eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/utils/CachingPasswordEncoder.java | 81 | 
1 files changed, 81 insertions, 0 deletions
| diff --git a/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/utils/CachingPasswordEncoder.java b/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/utils/CachingPasswordEncoder.java new file mode 100644 index 00000000..672ebb5e --- /dev/null +++ b/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/utils/CachingPasswordEncoder.java @@ -0,0 +1,81 @@ +package at.gv.egiz.eaaf.utils.springboot.utils; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.security.crypto.password.PasswordEncoder; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * Decorator for {@link PasswordEncoder} that caches valid password to speed-up password verification. + *  + * @author tlenz + * + */ +@Slf4j +@AllArgsConstructor +public class CachingPasswordEncoder implements PasswordEncoder { + +  /** +   * Cryptographic password encoder.  +   */ +  private final PasswordEncoder internalEncoder;      +   +  /** +   * Look-up table to speed-up password validation on REST API's. +   */ +  private final Map<String, String> passwordCache = new ConcurrentHashMap<>(10); +   +  @Override +  public String encode(CharSequence rawPassword) { +    log.trace("Delegate password encoding to: {}", internalEncoder.getClass().getName()); +    return internalEncoder.encode(rawPassword); +     +  } + +  @Override +  public boolean matches(CharSequence rawPassword, String encodedPassword) { +     +    if (passwordCache.containsKey(rawPassword.toString())) { +      log.trace("Find password in cache. Starting verification ... "); +      String cachedPassword = passwordCache.get(rawPassword).toString(); +      if (equalsNoEarlyReturn(cachedPassword, encodedPassword)) {         +        return true; +         +      } +    } +     +    return checkPasswordAndUpdateCache(rawPassword, encodedPassword); +             +  } +   +  @Override +  public boolean upgradeEncoding(String encodedPassword) { +    return internalEncoder.upgradeEncoding(encodedPassword); +     +  } +   +   +  private boolean checkPasswordAndUpdateCache(CharSequence rawPassword, String encodedPassword) { +    log.trace("Password not cached. Starting password processing ... "); +    boolean passwordValid = internalEncoder.matches(rawPassword, encodedPassword); +    if (passwordValid) { +      log.debug("Get valid password. Cached it for faster reusage"); +      passwordCache.put(rawPassword.toString(), encodedPassword); +       +    }  +     +    return passwordValid; +                 +  } + +  static boolean equalsNoEarlyReturn(String a, String b) { +    return MessageDigest.isEqual(a.getBytes(StandardCharsets.UTF_8), b.getBytes(StandardCharsets.UTF_8)); +     +  } + +} | 
