diff --git a/awardBE/src/main/java/edu/ncst/award/config/CustomDelegatingPasswordEncoder.java b/awardBE/src/main/java/edu/ncst/award/config/CustomDelegatingPasswordEncoder.java new file mode 100644 index 0000000..911aede --- /dev/null +++ b/awardBE/src/main/java/edu/ncst/award/config/CustomDelegatingPasswordEncoder.java @@ -0,0 +1,83 @@ +package edu.ncst.award.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.crypto.argon2.Argon2PasswordEncoder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +public class CustomDelegatingPasswordEncoder extends DelegatingPasswordEncoder { + + private static final String PREFIX = "{"; + + private static final String SUFFIX = "}"; + + + public CustomDelegatingPasswordEncoder(String idForEncode, Map idToPasswordEncoder) { + super(idForEncode, idToPasswordEncoder); + } + + @Override + public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) { + String id = extractId(prefixEncodedPassword); + if (id == null) { + prefixEncodedPassword = PREFIX + "bcrypt" + SUFFIX + prefixEncodedPassword; + } + return super.matches(rawPassword, prefixEncodedPassword); + } + + @SuppressWarnings("deprecation") + public static PasswordEncoder createDelegatingPasswordEncoder() { + String encodingId = "bcrypt"; + Map encoders = new HashMap<>(); + encoders.put(encodingId, new BCryptPasswordEncoder()); + encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder()); + encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder()); + encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5")); + encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()); + encoders.put("pbkdf2", new Pbkdf2PasswordEncoder()); + encoders.put("scrypt", new SCryptPasswordEncoder()); + encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1")); + encoders.put("SHA-256", + new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256")); + encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder()); + encoders.put("argon2", new Argon2PasswordEncoder()); + DelegatingPasswordEncoder customDelegatingPasswordEncoder = new CustomDelegatingPasswordEncoder(encodingId, encoders); + customDelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new PassWordMatcher()); + return customDelegatingPasswordEncoder; + } + + static private String extractId(String prefixEncodedPassword) { + if (prefixEncodedPassword == null) { + return null; + } + int start = prefixEncodedPassword.indexOf(PREFIX); + if (start != 0) { + return null; + } + int end = prefixEncodedPassword.indexOf(SUFFIX, start); + if (end < 0) { + return null; + } + return prefixEncodedPassword.substring(start + 1, end); + } + + static private class PassWordMatcher implements PasswordEncoder { + @Override + public String encode(CharSequence rawPassword) { + throw new UnsupportedOperationException("encode is not supported"); + } + + @Override + public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) { + String id = extractId(prefixEncodedPassword); + throw new IllegalArgumentException("There is no PasswordEncoder mapped for the id \"" + id + "\""); + } + } +}