From 6823c602420a5b11440a70c4172250213e2b28e9 Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Wed, 1 Jan 2020 20:38:46 +0800 Subject: [PATCH 1/2] =?UTF-8?q?UI=E7=99=BB=E5=BD=95=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=94=B9=E9=87=87=E7=94=A8=E6=9B=B4=E5=AE=89=E5=85=A8=E7=9A=84?= =?UTF-8?q?=E5=8A=A0=E5=AF=86=E7=AD=96=E7=95=A5=E5=8F=8A=E5=8F=AF=E9=80=9A?= =?UTF-8?q?=E8=BF=87-Dbistoury.ui.register=5Fdisabled=3Dtrue=E6=9D=A5?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E5=B8=90=E5=8F=B7=E6=B3=A8=E5=86=8C=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=201.=20=E6=97=A7=E5=AE=9E=E7=8E=B0=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E9=87=87=E7=94=A8AES=E5=8A=A0=E5=AF=86=E5=AD=98=E5=82=A8?= =?UTF-8?q?=EF=BC=8C=E6=98=AF=E5=8F=AF=E9=80=86=E7=9A=84=EF=BC=8C=E8=BF=99?= =?UTF-8?q?=E6=98=AF=E4=B8=8D=E5=90=88=E9=80=82=E7=9A=84=E3=80=82=E7=8E=B0?= =?UTF-8?q?=E6=94=B9=E4=B8=BASPI=E6=96=B9=E5=BC=8F=EF=BC=8C=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E6=98=AF=E9=87=87=E7=94=A8spring-security=E6=8E=A8?= =?UTF-8?q?=E8=8D=90=E7=9A=84Pbkdf2PasswordEncoder=20=20=20=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9SPI=E5=AE=9E=E7=8E=B0=E9=85=8D=E7=BD=AE=E8=A7=81?= =?UTF-8?q?=EF=BC=9AMETA-INF/services/org.springframework.security.crypto.?= =?UTF-8?q?password.PasswordEncoder=202.=20quick=20start=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=BA=94=E8=AF=A5=E7=A6=81=E7=94=A8=E5=B8=90?= =?UTF-8?q?=E5=8F=B7=E6=B3=A8=E5=86=8C=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E6=97=A0=E6=84=8F=E8=AF=86=E5=9C=B0=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E7=9A=84=E5=AE=89=E5=85=A8=E9=A3=8E=E9=99=A9=20=20=20?= =?UTF-8?q?=20=E5=90=8C=E6=97=B6=E4=B8=BA=E4=BA=86=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E5=BB=BA=E8=AE=AEquick=20start=E8=84=9A=E6=9C=AC=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E5=89=8D=E6=8C=87=E5=AE=9A=E5=AF=86=E7=A0=81=EF=BC=8C?= =?UTF-8?q?ie:=20`-DBISTOURY=5FADMIN=5FPWD=3Dxxx`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bistoury-ui-service-impl/pom.xml | 49 +++++++++++++++++- .../ui/security/PasswordEncoderMain.java | 13 +++++ .../impl/PasswordEncoder4OldAESCryptImpl.java | 26 ++++++++++ .../ui/service/impl/UserServiceImpl.java | 50 +++++++++++++++---- ...k.security.crypto.password.PasswordEncoder | 3 ++ .../ui/security/PasswordEncoderTest.java | 26 ++++++++++ bistoury-ui/src/bin/bistoury-ui-env.sh | 6 +-- script/h2/data.sql | 2 +- script/h2/h2.sh | 14 +++--- script/quick_start.sh | 11 +++- 10 files changed, 175 insertions(+), 25 deletions(-) create mode 100644 bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/security/PasswordEncoderMain.java create mode 100644 bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java create mode 100644 bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder create mode 100644 bistoury-ui-service-impl/src/test/java/qunar/tc/bistoury/ui/security/PasswordEncoderTest.java diff --git a/bistoury-ui-service-impl/pom.xml b/bistoury-ui-service-impl/pom.xml index 89eaba11..2aae1270 100644 --- a/bistoury-ui-service-impl/pom.xml +++ b/bistoury-ui-service-impl/pom.xml @@ -36,6 +36,43 @@ mysql mysql-connector-java + + org.slf4j + jcl-over-slf4j + + + org.bouncycastle + bcprov-jdk15on + 1.64 + runtime + + + org.springframework.security + spring-security-core + 4.2.13.RELEASE + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-aop + + + org.springframework + spring-expression + + + org.springframework + spring-core + + + ${project.artifactId} @@ -50,4 +87,14 @@ - \ No newline at end of file + + + + junit + junit + 4.12 + test + + + + diff --git a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/security/PasswordEncoderMain.java b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/security/PasswordEncoderMain.java new file mode 100644 index 00000000..e33bd68c --- /dev/null +++ b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/security/PasswordEncoderMain.java @@ -0,0 +1,13 @@ + package qunar.tc.bistoury.ui.security; + +import qunar.tc.bistoury.ui.service.impl.UserServiceImpl; + +public class PasswordEncoderMain { + + public static void main(String[] args) { + String rawPassword = args == null || args.length < 1 ? "admin" : args[0]; + String encodePwd = UserServiceImpl.encodePwd(rawPassword); + System.out.println("rawPassword: " + rawPassword + " encodePwd: " + encodePwd); + } + +} diff --git a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java new file mode 100644 index 00000000..dd386a3a --- /dev/null +++ b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java @@ -0,0 +1,26 @@ +package qunar.tc.bistoury.ui.service.impl; + +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * 此旧为实现,仅为兼容而存在 建议采用默认更安全的加密加密策略,实现需要 + * 实在需要,请在SPI定义文件META-INF\services\org.springframework.security.crypto.password.PasswordEncoder中配置此实现类 + * + * @author qxo + * @date 2020/01/01 + */ +public class PasswordEncoder4OldAESCryptImpl implements PasswordEncoder { + + private final AESCryptServiceImpl old = new AESCryptServiceImpl(); + + @Override + public String encode(CharSequence rawPassword) { + return rawPassword == null ? null : old.encrypt(rawPassword.toString()); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return rawPassword == null ? false : old.encrypt(rawPassword.toString()).equals(encodedPassword); + } + +} diff --git a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java index c65f7206..071454a5 100644 --- a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java +++ b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java @@ -17,23 +17,26 @@ package qunar.tc.bistoury.ui.service.impl; +import java.util.List; +import java.util.ServiceLoader; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.base.Strings; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import qunar.tc.bistoury.serverside.configuration.DynamicConfig; import qunar.tc.bistoury.serverside.configuration.DynamicConfigLoader; import qunar.tc.bistoury.serverside.configuration.local.LocalDynamicConfig; import qunar.tc.bistoury.ui.dao.UserDao; import qunar.tc.bistoury.ui.model.User; -import qunar.tc.bistoury.ui.service.AESCryptService; import qunar.tc.bistoury.ui.service.UserService; -import javax.annotation.PostConstruct; -import java.util.List; - /** * @author leix.xie * @date 2019/7/4 11:00 @@ -44,12 +47,19 @@ public class UserServiceImpl implements UserService { private static final Splitter SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults(); + private static final PasswordEncoder PASSWORD_ENCODER; + static { + ServiceLoader sloader = ServiceLoader.load(PasswordEncoder.class); + PASSWORD_ENCODER = sloader.iterator().next(); + } + + public static String encodePwd(String rawPassword) { + return PASSWORD_ENCODER.encode(rawPassword); + } + @Autowired private UserDao userDao; - @Autowired - private AESCryptService aesCryptService; - private List admins; @PostConstruct @@ -61,14 +71,22 @@ public void init() { @Override public boolean login(User user) { User checkUser = this.userDao.getUserByUserCode(user.getUserCode()); - if (checkUser == null || !this.aesCryptService.encrypt(user.getPassword()).equals(checkUser.getPassword())) { + if (checkUser == null || !PASSWORD_ENCODER.matches(user.getPassword(), checkUser.getPassword())) { return false; } return true; } + /** + * 为true表示禁止帐号注册功能 + */ + private final boolean disable4register = Boolean.getBoolean("bistoury.ui.register_disabled"); + @Override public int register(User user) { + if (disable4register) { + throw new IllegalAccessError("User register is disabled!"); + } Preconditions.checkNotNull(user, "user cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(user.getUserCode()), "user code cannot be null or empty"); Preconditions.checkArgument(!Strings.isNullOrEmpty(user.getPassword()), "password cannot be null or empty"); @@ -76,9 +94,19 @@ public int register(User user) { if (checkUser != null) { return -1; } - user.setPassword(this.aesCryptService.encrypt(user.getPassword())); + user.setPassword(PASSWORD_ENCODER.encode(user.getPassword())); return this.userDao.registerUser(user); } + + public boolean changePwd(String uid, String oldPwd, String newPwd) { + User checkUser = this.userDao.getUserByUserCode(uid); + if (checkUser == null || !PASSWORD_ENCODER.matches(oldPwd, checkUser.getPassword())) { + return false; + } + + int ret = userDao.updatePwd(uid, oldPwd, newPwd); + return ret > 0; + } @Override public boolean isAdmin(final String userCode) { diff --git a/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder b/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder new file mode 100644 index 00000000..265472af --- /dev/null +++ b/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder @@ -0,0 +1,3 @@ +org.springframework.security.crypto.password.Pbkdf2PasswordEncoder +#org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +#org.springframework.security.crypto.scrypt.SCryptPasswordEncoder diff --git a/bistoury-ui-service-impl/src/test/java/qunar/tc/bistoury/ui/security/PasswordEncoderTest.java b/bistoury-ui-service-impl/src/test/java/qunar/tc/bistoury/ui/security/PasswordEncoderTest.java new file mode 100644 index 00000000..987f6e4c --- /dev/null +++ b/bistoury-ui-service-impl/src/test/java/qunar/tc/bistoury/ui/security/PasswordEncoderTest.java @@ -0,0 +1,26 @@ +package qunar.tc.bistoury.ui.security; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; + +public class PasswordEncoderTest { + + @Test + public void test() { + PasswordEncoder[] passwordEncoders = new PasswordEncoder[] { + new Pbkdf2PasswordEncoder(), + new BCryptPasswordEncoder(), + new SCryptPasswordEncoder() + }; + final String rawPassword = "password"; + for (PasswordEncoder passwordEncoder : passwordEncoders) { + final String encoded = passwordEncoder.encode(rawPassword); + System.out.println(passwordEncoder.getClass()+" src: "+rawPassword + " => "+encoded); + Assert.assertTrue(passwordEncoder.matches(rawPassword, encoded)); + } + } +} diff --git a/bistoury-ui/src/bin/bistoury-ui-env.sh b/bistoury-ui/src/bin/bistoury-ui-env.sh index 825691b9..e3bb9e14 100644 --- a/bistoury-ui/src/bin/bistoury-ui-env.sh +++ b/bistoury-ui/src/bin/bistoury-ui-env.sh @@ -1,5 +1,5 @@ #!/bin/bash set -euo pipefail - -JAVA_HOME="/tmp/bistoury/java" -JAVA_OPTS="-Dbistoury.conf=$BISTOURY_COF_DIR -Dbistoury.cache=$BISTOURY_CACHE_DIR" +set +o nounset +test -z "$JAVA_HOME" && JAVA_HOME="/tmp/bistoury/java" +JAVA_OPTS="$JAVA_OPTS -Dbistoury.conf=$BISTOURY_COF_DIR -Dbistoury.cache=$BISTOURY_CACHE_DIR" diff --git a/script/h2/data.sql b/script/h2/data.sql index 8401ea22..18882cee 100644 --- a/script/h2/data.sql +++ b/script/h2/data.sql @@ -1,4 +1,4 @@ -insert into bistoury_user (user_code, password) values ('admin','q1mHvT20zskSnIHSF27d/A=='); +insert into bistoury_user (user_code, password) values ('admin','${admin_pwd}'); insert into bistoury_app(code, name, group_code, status, creator) values ('bistoury_demo_app','测试应用','tcdev',1,'admin'); insert into bistoury_user_app (app_code, user_code) values ('bistoury_demo_app','admin'); insert into bistoury_server (server_id, ip, port, host, log_dir, room, app_code, auto_jstack_enable, auto_jmap_histo_enable) values ('bade8ba7d59b4ca0b91a044739a670aa','${local_ip}',8080,'${local_host}','${log_dir}','al','bistoury_demo_app',1,0); diff --git a/script/h2/h2.sh b/script/h2/h2.sh index 8ad048d2..916521ad 100755 --- a/script/h2/h2.sh +++ b/script/h2/h2.sh @@ -3,14 +3,12 @@ H2_DIR=`pwd` H2_LOG_FILE=$H2_DIR/h2.log H2_PID_FILE=$H2_DIR/h2.pid -BISTOURY_TMP_DIR="/tmp/bistoury" +test -z "$BISTOURY_TMP_DIR" && BISTOURY_TMP_DIR="/tmp/bistoury" H2_PORT_FILE="$BISTOURY_TMP_DIR/h2port.conf" -H2_DATA_BASE_URL="/tmp/bistoury/h2/bistoury;MODE=MYSQL;TRACE_LEVEL_SYSTEM_OUT=2;AUTO_SERVER=TRUE;" +H2_DATA_BASE_URL="${BISTOURY_TMP_DIR}/h2/bistoury;MODE=MYSQL;TRACE_LEVEL_SYSTEM_OUT=2;AUTO_SERVER=TRUE;" APP_LOG_DIR="\/tmp" -LOCAL_IP=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|tail -1` - H2_PORT=9092; echo "$H2_PORT">$H2_PORT_FILE @@ -36,7 +34,6 @@ else fi start(){ - echo "Init tables" $JAVA -cp h2-1.4.199.jar org.h2.tools.RunScript -url "jdbc:h2:file:$H2_DATA_BASE_URL" -script ./schema.sql @@ -44,10 +41,13 @@ start(){ #替换数据库初始化文件中的sql local_host=`hostname` APP_LOG_DIR=` echo $APP_LOG_DIR | sed 's#\/#\\\/#g'` - sed 's/${local_ip}/'$LOCAL_IP'/g' data.sql | sed 's/${local_host}/'$local_host'/g'|sed 's/${log_dir}/'$APP_LOG_DIR'/g' >newdata.sql + test -z "$LOCAL_IP" && LOCAL_IP=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|tail -1` + test -z "$BISTOURY_ADMIN_PWD" && export BISTOURY_ADMIN_PWD="q1mHvT20zskSnIHSF27d/A==" + sed 's@${local_ip}@'$LOCAL_IP'@g' data.sql | sed 's@${admin_pwd}@'$BISTOURY_ADMIN_PWD'@g' | \ + sed 's/${local_host}/'$local_host'/g'|sed 's@${log_dir}@'$APP_LOG_DIR'@g' >newdata.sql $JAVA -cp h2-1.4.199.jar org.h2.tools.RunScript -url "jdbc:h2:file:$H2_DATA_BASE_URL" -script ./newdata.sql - + unset BISTOURY_ADMIN_PWD rm -rf newdata.sql echo "Start h2 database" diff --git a/script/quick_start.sh b/script/quick_start.sh index 077df3ee..e89516a4 100755 --- a/script/quick_start.sh +++ b/script/quick_start.sh @@ -19,12 +19,19 @@ BISTOURY_AGENT_APP_LIB_CLASS=""; BISTOURY_TMP_DIR="/tmp/bistoury" BISTOURY_PROXY_CONF_FILE="$BISTOURY_TMP_DIR/proxy.conf" -LOCAL_IP=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|tail -1` - start(){ + test -z "$LOCAL_IP" && LOCAL_IP=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|tail -1` + export JAVA_OPTS="$JAVA_OPTS -Dbistoury.ui.register_disabled=true" + test -z "$BISTOURY_ADMIN_PWD" && BISTOURY_ADMIN_PWD=admin + cd $BISTOURY_UI_BIN_DIR + echo "BISTOURY_ADMIN_PWD=$BISTOURY_ADMIN_PWD" + export BISTOURY_ADMIN_PWD=$(java -cp '../lib/*' qunar.tc.bistoury.ui.security.PasswordEncoderMain "$BISTOURY_ADMIN_PWD" | awk '/encodePwd:/{print $4}') + #echo "BISTOURY_ADMIN_PWD=$BISTOURY_ADMIN_PWD" + cd $H2_DATABASE_DIR ./h2.sh -j $2 -i $LOCAL_IP -l $APP_LOG_DIR start + unset BISTOURY_ADMIN_PWD sleep 5 cd $BISTOURY_PROXY_BIN_DIR From b0260a71ddf23424bbd07b061800a9a40cde1c6d Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Sun, 26 Jan 2020 16:54:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=91=BD=E5=90=8D;?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=8E=AF=E5=A2=83=E6=9D=A5=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E5=8A=A0=E5=AF=86=E5=99=A8=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=B1=BB,=E4=B8=BA=E4=BA=86=E5=85=BC=E5=AE=B9=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E4=B8=BA=E6=97=A7=E6=96=B9=E5=BC=8F=20quick=20start?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=E5=90=AF=E7=94=A8=E6=96=B0=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?,=E5=8D=B3:=20`export=20BISTOURY=5FUI=5FPASSWORD=5FENCODER=3Dne?= =?UTF-8?q?w`=20=E4=B9=9F=E5=8F=AF=E5=BC=BA=E5=88=B6=E6=97=A7=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F:=20`export=20BISTOURY=5FUI=5FPASSWORD=5FENCODER=3Dold?= =?UTF-8?q?`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...=> PasswordEncoderForOldAESCryptImpl.java} | 8 ++-- .../ui/service/impl/UserServiceImpl.java | 45 ++++++++++++------- ...k.security.crypto.password.PasswordEncoder | 3 +- script/quick_start.sh | 1 + 4 files changed, 37 insertions(+), 20 deletions(-) rename bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/{PasswordEncoder4OldAESCryptImpl.java => PasswordEncoderForOldAESCryptImpl.java} (61%) diff --git a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoderForOldAESCryptImpl.java similarity index 61% rename from bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java rename to bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoderForOldAESCryptImpl.java index dd386a3a..2965cd03 100644 --- a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoder4OldAESCryptImpl.java +++ b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/PasswordEncoderForOldAESCryptImpl.java @@ -9,18 +9,18 @@ * @author qxo * @date 2020/01/01 */ -public class PasswordEncoder4OldAESCryptImpl implements PasswordEncoder { +public class PasswordEncoderForOldAESCryptImpl implements PasswordEncoder { - private final AESCryptServiceImpl old = new AESCryptServiceImpl(); + private final AESCryptServiceImpl aesCryptService = new AESCryptServiceImpl(); @Override public String encode(CharSequence rawPassword) { - return rawPassword == null ? null : old.encrypt(rawPassword.toString()); + return rawPassword == null ? null : aesCryptService.encrypt(rawPassword.toString()); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { - return rawPassword == null ? false : old.encrypt(rawPassword.toString()).equals(encodedPassword); + return rawPassword == null ? false : aesCryptService.encrypt(rawPassword.toString()).equals(encodedPassword); } } diff --git a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java index 071454a5..e7c0f34a 100644 --- a/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java +++ b/bistoury-ui-service-impl/src/main/java/qunar/tc/bistoury/ui/service/impl/UserServiceImpl.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; import org.springframework.stereotype.Service; import com.google.common.base.Preconditions; @@ -47,12 +48,36 @@ public class UserServiceImpl implements UserService { private static final Splitter SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults(); + /** + * 密码加密器,可通过环境变理BISTOURY_UI_PASSWORD_ENCODER来指定实现类, + * 也可用new表示采用推存的加密实现类:Pbkdf2PasswordEncoder + * 用old表示旧实现PasswordEncoderForOldAESCryptImpl + * 如未指定默认采用SPI方式,且SPI默认实现为旧的PasswordEncoderForOldAESCryptImpl + */ private static final PasswordEncoder PASSWORD_ENCODER; static { - ServiceLoader sloader = ServiceLoader.load(PasswordEncoder.class); - PASSWORD_ENCODER = sloader.iterator().next(); + String cls = System.getenv("BISTOURY_UI_PASSWORD_ENCODER"); + if ("new".equals(cls)) { + PASSWORD_ENCODER = new Pbkdf2PasswordEncoder(); + } else if ("old".equals(cls)) { + PASSWORD_ENCODER = new PasswordEncoderForOldAESCryptImpl(); + } else if (cls != null) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + PASSWORD_ENCODER = (PasswordEncoder)classLoader.loadClass(cls).newInstance(); + } catch (InstantiationException e) { + throw new IllegalStateException(e); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + } else { + ServiceLoader sloader = ServiceLoader.load(PasswordEncoder.class); + PASSWORD_ENCODER = sloader.iterator().next(); + } } - + public static String encodePwd(String rawPassword) { return PASSWORD_ENCODER.encode(rawPassword); } @@ -80,11 +105,11 @@ public boolean login(User user) { /** * 为true表示禁止帐号注册功能 */ - private final boolean disable4register = Boolean.getBoolean("bistoury.ui.register_disabled"); + private final boolean disableRegister = Boolean.getBoolean("bistoury.ui.register_disabled"); @Override public int register(User user) { - if (disable4register) { + if (disableRegister) { throw new IllegalAccessError("User register is disabled!"); } Preconditions.checkNotNull(user, "user cannot be null"); @@ -97,16 +122,6 @@ public int register(User user) { user.setPassword(PASSWORD_ENCODER.encode(user.getPassword())); return this.userDao.registerUser(user); } - - public boolean changePwd(String uid, String oldPwd, String newPwd) { - User checkUser = this.userDao.getUserByUserCode(uid); - if (checkUser == null || !PASSWORD_ENCODER.matches(oldPwd, checkUser.getPassword())) { - return false; - } - - int ret = userDao.updatePwd(uid, oldPwd, newPwd); - return ret > 0; - } @Override public boolean isAdmin(final String userCode) { diff --git a/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder b/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder index 265472af..23c3e708 100644 --- a/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder +++ b/bistoury-ui-service-impl/src/main/resources/META-INF/services/org.springframework.security.crypto.password.PasswordEncoder @@ -1,3 +1,4 @@ -org.springframework.security.crypto.password.Pbkdf2PasswordEncoder +qunar.tc.bistoury.ui.service.impl.PasswordEncoderForOldAESCryptImpl +#org.springframework.security.crypto.password.Pbkdf2PasswordEncoder #org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder #org.springframework.security.crypto.scrypt.SCryptPasswordEncoder diff --git a/script/quick_start.sh b/script/quick_start.sh index e89516a4..65a9ff1c 100755 --- a/script/quick_start.sh +++ b/script/quick_start.sh @@ -28,6 +28,7 @@ start(){ echo "BISTOURY_ADMIN_PWD=$BISTOURY_ADMIN_PWD" export BISTOURY_ADMIN_PWD=$(java -cp '../lib/*' qunar.tc.bistoury.ui.security.PasswordEncoderMain "$BISTOURY_ADMIN_PWD" | awk '/encodePwd:/{print $4}') #echo "BISTOURY_ADMIN_PWD=$BISTOURY_ADMIN_PWD" + export BISTOURY_UI_PASSWORD_ENCODER=new cd $H2_DATABASE_DIR ./h2.sh -j $2 -i $LOCAL_IP -l $APP_LOG_DIR start