让liferay 支持 LDAP SSHA加密方式
最近公司的邮件服务器改成了ZIMBRA,ZIMBRA的LDAP使用了SSHA 加密方式,但是LIFERAY不支持,看了一下LIFERAY的代码,我写了一个patch。
ssha.patch
--- LDAPAuth.java2007-03-01 23:42:18.000000000 +0800
+++ /liferay/portal-ejb/src/com/liferay/portal/security/auth/LDAPAuth.java2007-03-01 23:11:33.000000000 +0800
@@ -28,6 +28,7 @@
import com.liferay.portal.kernel.log.LogUtil;
import com.liferay.portal.kernel.util.StackTraceUtil;
import com.liferay.portal.kernel.util.StringPool;
+import com.liferay.portal.kernel.util.Base64;
import com.liferay.portal.model.User;
import com.liferay.portal.security.ldap.LDAPImportUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
@@ -54,6 +55,10 @@
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import sun.misc.BASE64Encoder;
+
/**
* View Source
*
@@ -261,23 +266,11 @@
if (userPassword != null) {
String ldapPassword = new String((byte[])userPassword.get());
-String encryptedPassword = password;
-
-String algorithm = PrefsPropsUtil.getString(
-companyId,
-PropsUtil.AUTH_IMPL_LDAP_PASSWORD_ENCRYPTION_ALGORITHM);
-
-if (Validator.isNotNull(algorithm)) {
-encryptedPassword =
-"{" + algorithm + "}" +
-Encryptor.digest(algorithm, password);
-}
-
-if (!ldapPassword.equals(encryptedPassword)) {
+if (!verifyPassword(ldapPassword,password)) {
_log.error(
"LDAP password " + ldapPassword +
" does not match with given password " +
-encryptedPassword + " for user id " + userId);
+password + " for user id " + userId);
return false;
}
@@ -381,6 +374,98 @@
locationId, sendEmail, true, true);
}
+ /**
+ * Splits a byte array into two.
+ *
+ * @param src byte array to split
+ * @param n location to split the array
+ * @return a two dimensional array of the split
+ */
+ private static byte[][] split(byte[] src, int n) {
+ byte[] l;
+ byte[] r;
+
+ if (src.length <= n) {
+ l = src;
+ r = new byte[0];
+
+ } else {
+ l = new byte[n];
+ r = new byte[src.length - n];
+ System.arraycopy(src, 0, l, 0, n);
+ System.arraycopy(src, n, r, 0, r.length);
+
+ }
+
+ byte[][] lr = { l, r };
+
+ return lr;
+
+ }
+
+
+ /**
+ * Validates if a plaintext password matches a
+ * hashed version.
+ *
+ * @param digest digested version
+ * @param password plaintext password
+ * @return if the two match
+ */
+ public static boolean verifyPassword(String digest, String password) {
+ String alg = null;
+ int size = 0;
+
+ if (digest.regionMatches(true, 0, "{SHA}", 0, 5)) {
+ digest = digest.substring(5);
+ alg = "SHA-1";
+ size = 20;
+
+ } else if (digest.regionMatches(true, 0, "{SSHA}", 0, 6)) {
+ digest = digest.substring(6);
+ alg = "SHA-1";
+ size = 20;
+
+ } else if (digest.regionMatches(true, 0, "{MD5}", 0, 5)) {
+ digest = digest.substring(5);
+ alg = "MD5";
+ size = 16;
+
+ } else if (digest.regionMatches(true, 0, "{SMD5}", 0, 6)) {
+ digest = digest.substring(6);
+ alg = "MD5";
+ size = 16;
+
+ }
+
+ try {
+ MessageDigest mDigest = MessageDigest.getInstance(alg);
+
+ if (mDigest == null) {
+ return false;
+
+ }
+
+ byte[][] hs = split(Base64.decode(digest), size);
+ byte[] hash = hs[0];
+ byte[] salt = hs[1];
+ mDigest.reset();
+ mDigest.update(password.getBytes());
+ mDigest.update(salt);
+
+ byte[] pwhash = mDigest.digest();
+
+ return MessageDigest.isEqual(hash, pwhash);
+
+ } catch (NoSuchAlgorithmException nsae) {
+_log.error(StackTraceUtil.getStackTrace(nsae));
+return false;
+ }
+
+ }
+
+
+
private static Log _log = LogFactoryUtil.getLog(LDAPAuth.class);
-}
\ No newline at end of file
+}
1 楼 pikachu 2007-03-22 谢谢chinaet热心帮助