2012-02-12 02:55:42 -03:00
|
|
|
/*
|
2022-03-17 18:47:34 -03:00
|
|
|
* Copyright [2022] [wisemapping]
|
2020-11-07 11:56:38 -08:00
|
|
|
*
|
|
|
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
|
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
|
|
* "powered by wisemapping" text requirement on every single page;
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the license at
|
|
|
|
*
|
|
|
|
* http://www.wisemapping.org/license
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2012-02-12 02:55:42 -03:00
|
|
|
|
|
|
|
package com.wisemapping.security;
|
|
|
|
|
2020-11-08 12:08:13 -08:00
|
|
|
import org.apache.log4j.Logger;
|
2020-11-08 15:29:42 -08:00
|
|
|
import org.springframework.security.crypto.codec.Base64;
|
|
|
|
import org.springframework.security.crypto.codec.Hex;
|
|
|
|
import org.springframework.security.crypto.codec.Utf8;
|
2020-11-07 11:56:38 -08:00
|
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
2020-11-08 15:29:42 -08:00
|
|
|
|
|
|
|
import java.security.MessageDigest;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
|
2012-02-12 02:55:42 -03:00
|
|
|
|
2020-11-08 12:08:13 -08:00
|
|
|
public class LegacyPasswordEncoder implements PasswordEncoder {
|
2021-12-24 18:03:23 -08:00
|
|
|
final private static Logger logger = Logger.getLogger(LegacyPasswordEncoder.class);
|
2020-11-08 12:08:13 -08:00
|
|
|
|
2021-12-24 18:03:23 -08:00
|
|
|
public static final String ENC_PREFIX = "ENC:";
|
2020-11-08 15:29:42 -08:00
|
|
|
private final ShaPasswordEncoder sha1Encoder = new ShaPasswordEncoder();
|
2012-02-12 02:55:42 -03:00
|
|
|
|
2020-11-07 11:56:38 -08:00
|
|
|
@Override
|
|
|
|
public String encode(CharSequence rawPassword) {
|
2020-11-08 12:08:13 -08:00
|
|
|
|
2020-11-22 13:12:03 -08:00
|
|
|
logger.debug("LegacyPasswordEncoder encode executed.");
|
2020-11-08 15:29:42 -08:00
|
|
|
return ENC_PREFIX + sha1Encoder.encode(rawPassword.toString(), "");
|
2020-11-08 12:08:13 -08:00
|
|
|
|
2012-02-12 02:55:42 -03:00
|
|
|
}
|
|
|
|
|
2020-11-07 11:56:38 -08:00
|
|
|
@Override
|
|
|
|
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
2012-02-12 02:55:42 -03:00
|
|
|
|
2020-11-08 13:43:38 -08:00
|
|
|
final String encode = encode(rawPassword);
|
|
|
|
return encode.equals(encodedPassword);
|
2012-02-12 02:55:42 -03:00
|
|
|
}
|
|
|
|
}
|
2020-11-08 15:29:42 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Just copied to keep compatibility with Spring 3.
|
|
|
|
*/
|
|
|
|
class ShaPasswordEncoder {
|
|
|
|
|
|
|
|
private final String algorithm;
|
2021-12-24 18:03:23 -08:00
|
|
|
private final boolean encodeHashAsBase64;
|
2020-11-08 15:29:42 -08:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The digest algorithm to use
|
|
|
|
* Supports the named <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA">
|
|
|
|
* Message Digest Algorithms</a> in the Java environment.
|
|
|
|
**/
|
|
|
|
ShaPasswordEncoder() {
|
|
|
|
|
|
|
|
this("SHA-1", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience constructor for specifying the algorithm and whether or not to enable base64 encoding
|
|
|
|
*
|
|
|
|
* @param algorithm
|
|
|
|
* @param encodeHashAsBase64
|
|
|
|
* @throws IllegalArgumentException if an unknown
|
|
|
|
*/
|
|
|
|
private ShaPasswordEncoder(String algorithm, boolean encodeHashAsBase64) throws IllegalArgumentException {
|
|
|
|
this.algorithm = algorithm;
|
|
|
|
this.encodeHashAsBase64 = encodeHashAsBase64;
|
|
|
|
getMessageDigest();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Encodes the rawPass using a MessageDigest.
|
|
|
|
* If a salt is specified it will be merged with the password before encoding.
|
|
|
|
*
|
|
|
|
* @param rawPass The plain text password
|
|
|
|
* @param salt The salt to sprinkle
|
|
|
|
* @return Hex string of password digest (or base64 encoded string if encodeHashAsBase64 is enabled.
|
|
|
|
*/
|
|
|
|
public String encode(String rawPass, Object salt) {
|
|
|
|
String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
|
|
|
|
|
|
|
|
MessageDigest messageDigest = getMessageDigest();
|
|
|
|
|
|
|
|
byte[] digest = messageDigest.digest(Utf8.encode(saltedPass));
|
|
|
|
|
|
|
|
if (getEncodeHashAsBase64()) {
|
|
|
|
return Utf8.decode(Base64.encode(digest));
|
|
|
|
} else {
|
|
|
|
return new String(Hex.encode(digest));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a MessageDigest instance for the given algorithm.
|
|
|
|
* Throws an IllegalArgumentException if <i>algorithm</i> is unknown
|
|
|
|
*
|
|
|
|
* @return MessageDigest instance
|
|
|
|
* @throws IllegalArgumentException if NoSuchAlgorithmException is thrown
|
|
|
|
*/
|
|
|
|
private final MessageDigest getMessageDigest() throws IllegalArgumentException {
|
|
|
|
try {
|
|
|
|
return MessageDigest.getInstance(algorithm);
|
|
|
|
} catch (NoSuchAlgorithmException e) {
|
|
|
|
throw new IllegalArgumentException("No such algorithm [" + algorithm + "]");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//~ Methods ========================================================================================================
|
|
|
|
|
|
|
|
private boolean getEncodeHashAsBase64() {
|
|
|
|
return encodeHashAsBase64;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String mergePasswordAndSalt(String password, Object salt, boolean strict) {
|
|
|
|
if (password == null) {
|
|
|
|
password = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strict && (salt != null)) {
|
|
|
|
if ((salt.toString().lastIndexOf("{") != -1)
|
|
|
|
|| (salt.toString().lastIndexOf("}") != -1)) {
|
|
|
|
throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((salt == null) || "".equals(salt)) {
|
|
|
|
return password;
|
|
|
|
} else {
|
|
|
|
return password + "{" + salt.toString() + "}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|