diff --git a/docs/authn/fgpwd.md b/docs/authn/fgpwd.md index eebdc8113..723303d48 100644 --- a/docs/authn/fgpwd.md +++ b/docs/authn/fgpwd.md @@ -27,10 +27,17 @@ 2、电子邮件 -
+#SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
+config.otp.sms=SmsOtpAuthnYunxin
+
-<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud">
- <property name="secretId" value="94395d754eb55693043f5d6a2b772ef4" />
- <property name="secretKey" value="05d5485357bc" />
- <property name="smsSdkAppid" value="1486220095" />
- <property name="templateId" value="14860095" />
- <property name="sign" value="1486009522" />
-</bean>
-
+
+config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.aliyun.accesssecret=05d5485357bc
+config.otp.sms.aliyun.templatecode=14860095
+config.otp.sms.aliyun.signname=maxkey
阿里云短信
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中maxkey.properties
accessKeyId 账号Appkey
@@ -63,18 +66,16 @@ templateCode 短信模板ID
signName 签名
-
-<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun">
- <property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" />
- <property name="accessSecret" value="05d5485357bc" />
- <property name="templateCode" value="SMS_187590021" />
- <property name="signName" value="MaxKey" />
-</bean>
-
+
+config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.tencentcloud.secretkey=05d5485357bc
+config.otp.sms.tencentcloud.smssdkappid=1486220095
+config.otp.sms.tencentcloud.templateid=14860095
+config.otp.sms.tencentcloud.sign=1486009522
网易云信
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中maxkey.properties
appKey 网易云信分配的账号Appkey
@@ -82,13 +83,10 @@ appSecret 网易云信分配的密钥appSecret
templateId 短信模板ID
-
-<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin">
- <property name="appKey" value="94395d754eb55693043f5d6a2b772ef4" />
- <property name="appSecret" value="05d5485357bc" />
- <property name="templateId" value="14860095" />
-</bean>
-
+
+config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.yunxin.appsecret=05d5485357bc
+config.otp.sms.yunxin.templateid=14860095
电子邮件
@@ -96,28 +94,26 @@ templateId 短信模板ID
配置邮箱地址
文件
-maxkey/config/applicationConfig.properties
+maxkey/application.properties
-# EMAIL configuration
-config.email.username=maxkey@163.com
-config.email.password=password
-config.email.smtpHost=smtp.163.com
-config.email.port=465
-config.email.senderMail=maxkey@163.com
-config.email.ssl=true
+spring.mail.default-encoding=utf-8
+spring.mail.host=smtp.163.com
+spring.mail.port=465
+spring.mail.username=maxkey@163.com
+spring.mail.password=password
+spring.mail.protocol=smtp
+spring.mail.properties.ssl=true
+spring.mail.properties.sender=maxkey@163.com
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中application.properties
subject 邮件主题
messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔
-
-
-<bean id="tfaMailOptAuthn" class="org.maxkey.crypto.password.opt.impl.MailOtpAuthn">
- <property name="subject" value="MaxKey One Time PassWord" />
- <property name="messageTemplate" value="{0} You Token is {1} , it validity in {2} minutes." />
-</bean>
+
+spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
+spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
\ No newline at end of file
diff --git a/docs/authn/mfa.md b/docs/authn/mfa.md
index c2be9862e..11b365031 100644
--- a/docs/authn/mfa.md
+++ b/docs/authn/mfa.md
@@ -14,8 +14,16 @@
短信认证
+配置maxkey中maxkey.properties
+
+
+config.login.mfa=true
+#TimeBasedOtpAuthn MailOtpAuthn SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
+config.login.mfa.type=TimeBasedOtpAuthn
+
+
腾讯云短信
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中maxkey.properties
secretId 账号Appkey
secretKey 密钥appSecret
@@ -26,23 +34,15 @@ templateId 短信模板ID
sign 签名
-
-<!--
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
-</bean>
--->
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud">
- <property name="secretId" value="94395d754eb55693043f5d6a2b772ef4" />
- <property name="secretKey" value="05d5485357bc" />
- <property name="smsSdkAppid" value="1486220095" />
- <property name="templateId" value="14860095" />
- <property name="sign" value="1486009522" />
-</bean>
-
+
+config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.aliyun.accesssecret=05d5485357bc
+config.otp.sms.aliyun.templatecode=14860095
+config.otp.sms.aliyun.signname=maxkey
阿里云短信
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中maxkey.properties
accessKeyId 账号Appkey
@@ -52,22 +52,16 @@ templateCode 短信模板ID
signName 签名
-
-<!--
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
-</bean>
--->
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun">
- <property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" />
- <property name="accessSecret" value="05d5485357bc" />
- <property name="templateCode" value="SMS_187590021" />
- <property name="signName" value="MaxKey" />
-</bean>
-
+
+config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.tencentcloud.secretkey=05d5485357bc
+config.otp.sms.tencentcloud.smssdkappid=1486220095
+config.otp.sms.tencentcloud.templateid=14860095
+config.otp.sms.tencentcloud.sign=1486009522
网易云信
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中maxkey.properties
appKey 网易云信分配的账号Appkey
@@ -75,17 +69,10 @@ appSecret 网易云信分配的密钥appSecret
templateId 短信模板ID
-
-<!--
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
-</bean>
--->
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin">
- <property name="appKey" value="94395d754eb55693043f5d6a2b772ef4" />
- <property name="appSecret" value="05d5485357bc" />
- <property name="templateId" value="14860095" />
-</bean>
-
+
+config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.yunxin.appsecret=05d5485357bc
+config.otp.sms.yunxin.templateid=14860095
电子邮件
@@ -93,31 +80,27 @@ templateId 短信模板ID
配置邮箱地址
文件
-maxkey/config/applicationConfig.properties
+maxkey/application.properties
# EMAIL configuration
-config.email.username=maxkey@163.com
-config.email.password=password
-config.email.smtpHost=smtp.163.com
-config.email.port=465
-config.email.senderMail=maxkey@163.com
-config.email.ssl=true
+spring.mail.default-encoding=utf-8
+spring.mail.host=smtp.163.com
+spring.mail.port=465
+spring.mail.username=maxkey@163.com
+spring.mail.password=password
+spring.mail.protocol=smtp
+spring.mail.properties.ssl=true
+spring.mail.properties.sender=maxkey@163.com
-配置maxkey中spring/maxkey-security.xml
+配置maxkey中application.properties
subject 邮件主题
messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔
-
-<!--
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
-</bean>
--->
-<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.MailOtpAuthn">
- <property name="subject" value="MaxKey One Time PassWord" />
- <property name="messageTemplate" value="{0} You Token is {1} , it validity in {2} minutes." />
-</bean>
+
+spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
+spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
\ No newline at end of file
diff --git a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java b/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
index 4fe47fa39..33556e3cd 100644
--- a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
+++ b/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
@@ -188,7 +188,7 @@ public abstract class AbstractAuthenticationProvider {
*/
protected void tftcaptchaValid(String otpCaptcha, String authType, UserInfo userInfo) {
// for one time password 2 factor
- if (applicationConfig.getLoginConfig().isOneTimePwd() && authType.equalsIgnoreCase("tfa")) {
+ if (applicationConfig.getLoginConfig().isMfa() && authType.equalsIgnoreCase("tfa")) {
UserInfo validUserInfo = new UserInfo();
validUserInfo.setUsername(userInfo.getUsername());
String sharedSecret =
diff --git a/maxkey-core/src/main/java/org/maxkey/config/LoginConfig.java b/maxkey-core/src/main/java/org/maxkey/config/LoginConfig.java
index ded65f793..f9c40645a 100644
--- a/maxkey-core/src/main/java/org/maxkey/config/LoginConfig.java
+++ b/maxkey-core/src/main/java/org/maxkey/config/LoginConfig.java
@@ -15,8 +15,8 @@ public class LoginConfig {
@Value("${config.login.captcha.type:text}")
String captchaType;
- @Value("${config.login.onetimepwd}")
- boolean oneTimePwd;
+ @Value("${config.login.mfa}")
+ boolean mfa;
@Value("${config.login.socialsignon}")
boolean socialSignOn;
@@ -48,14 +48,6 @@ public class LoginConfig {
this.captcha = captcha;
}
- public boolean isOneTimePwd() {
- return oneTimePwd;
- }
-
- public void setOneTimePwd(boolean oneTimePwd) {
- this.oneTimePwd = oneTimePwd;
- }
-
public boolean isSocialSignOn() {
return socialSignOn;
}
@@ -72,6 +64,14 @@ public class LoginConfig {
this.kerberos = kerberos;
}
+ public boolean isMfa() {
+ return mfa;
+ }
+
+ public void setMfa(boolean mfa) {
+ this.mfa = mfa;
+ }
+
public String getDefaultUri() {
return defaultUri;
}
@@ -109,7 +109,7 @@ public class LoginConfig {
StringBuilder builder = new StringBuilder();
builder
.append("LoginConfig [captcha=").append(captcha)
- .append(", oneTimePwd=").append(oneTimePwd)
+ .append(", mfa=").append(mfa)
.append(", socialSignOn=").append(socialSignOn)
.append(", kerberos=").append(kerberos)
.append(", remeberMe=").append(remeberMe)
diff --git a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java
index ad13f1e3d..8201ccf8c 100644
--- a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java
+++ b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java
@@ -1,15 +1,26 @@
package org.maxkey.crypto.password.opt.impl;
+import java.io.IOException;
+import java.util.Properties;
+import org.maxkey.constants.ConstantsProperties;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
public class SmsOtpAuthn extends AbstractOptAuthn {
-
+ private static final Logger logger = LoggerFactory.getLogger(SmsOtpAuthn.class);
+
+ protected Properties properties;
+
+
@Override
public boolean produce(UserInfo userInfo) {
String token = this.genToken(userInfo);
// TODO:You must add send sms code here
-
+ logger.debug("send sms code" + token);
return true;
}
@@ -17,5 +28,18 @@ public class SmsOtpAuthn extends AbstractOptAuthn {
public boolean validate(UserInfo userInfo, String token) {
return true;
}
+
+ protected void loadProperties() throws IOException {
+ Resource resource = new ClassPathResource(
+ ConstantsProperties.classPathResource(
+ ConstantsProperties.classPathResource(
+ ConstantsProperties.maxKeyPropertySource)));
+ properties = new Properties();
+ properties.load(resource.getInputStream());
+ }
+
+ public void initPropertys() {
+
+ }
}
diff --git a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnAliyun.java b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnAliyun.java
index cb168fbe2..bf90ced5e 100644
--- a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnAliyun.java
+++ b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnAliyun.java
@@ -6,6 +6,9 @@ import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
+
+import java.io.IOException;
+
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
@@ -110,4 +113,18 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
this.signName = signName;
}
+ @Override
+ public void initPropertys() {
+ try {
+ this.loadProperties();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ this.accessKeyId = this.properties.getProperty("config.otp.sms.aliyun.accesskeyid");
+ this.accessSecret = this.properties.getProperty("config.otp.sms.aliyun.accesssecret");
+ this.templateCode = this.properties.getProperty("config.otp.sms.aliyun.templatecode");
+ this.signName = this.properties.getProperty("config.otp.sms.aliyun.signname");
+ }
+
}
diff --git a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnTencentCloud.java b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnTencentCloud.java
index 36bf97750..28023e0d3 100644
--- a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnTencentCloud.java
+++ b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnTencentCloud.java
@@ -6,6 +6,9 @@ import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
+
+import java.io.IOException;
+
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
@@ -153,4 +156,19 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
this.sign = sign;
}
+ @Override
+ public void initPropertys() {
+ try {
+ this.loadProperties();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ this.secretId = this.properties.getProperty("config.otp.sms.tencentcloud.secretid");
+ this.secretKey = this.properties.getProperty("config.otp.sms.tencentcloud.secretkey");
+ this.smsSdkAppid = this.properties.getProperty("config.otp.sms.tencentcloud.smssdkappid");
+ this.templateId = this.properties.getProperty("config.otp.sms.tencentcloud.templateid");
+ this.sign = this.properties.getProperty("config.otp.sms.tencentcloud.sign");
+ }
+
}
diff --git a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnYunxin.java b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnYunxin.java
index a01f7c254..4d722f616 100644
--- a/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnYunxin.java
+++ b/maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SmsOtpAuthnYunxin.java
@@ -1,5 +1,6 @@
package org.maxkey.crypto.password.opt.impl.sms;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -184,6 +185,19 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
}
+ @Override
+ public void initPropertys() {
+ try {
+ this.loadProperties();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ this.appKey = this.properties.getProperty("config.otp.sms.yunxin.appkey");
+ this.appSecret = this.properties.getProperty("config.otp.sms.yunxin.appsecret");
+ this.templateId = this.properties.getProperty("config.otp.sms.yunxin.templateid");
+ }
+
/**
* main.
* @param args String
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
index cfa7fcdab..7a99a32a9 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
@@ -16,10 +16,13 @@ import org.maxkey.authn.support.kerberos.KerberosProxy;
import org.maxkey.authn.support.kerberos.RemoteKerberosService;
import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter;
import org.maxkey.constants.ConstantsProperties;
+import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.crypto.password.opt.algorithm.KeyUriFormat;
import org.maxkey.crypto.password.opt.impl.MailOtpAuthn;
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn;
+import org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun;
+import org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud;
import org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils;
@@ -180,27 +183,65 @@ public class MaxKeyConfig implements InitializingBean {
return authenticationRealm;
}
+ //default tfaOptAuthn
@Bean(name = "tfaOptAuthn")
- public TimeBasedOtpAuthn tfaOptAuthn() {
- TimeBasedOtpAuthn tfaOptAuthn = new TimeBasedOtpAuthn();
- _logger.debug("TimeBasedOtpAuthn inited.");
- return tfaOptAuthn;
+ public AbstractOptAuthn tfaOptAuthn(
+ @Value("${config.login.mfa.type}")String mfaType) {
+
+ if(mfaType.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
+ SmsOtpAuthnAliyun tfaOptAuthn = new SmsOtpAuthnAliyun();
+ tfaOptAuthn.initPropertys();
+ _logger.debug("SmsOtpAuthnAliyun inited.");
+ return tfaOptAuthn;
+ }else if(mfaType.equalsIgnoreCase("SmsOtpAuthnTencentCloud")) {
+ SmsOtpAuthnTencentCloud tfaOptAuthn = new SmsOtpAuthnTencentCloud();
+ tfaOptAuthn.initPropertys();
+ _logger.debug("SmsOtpAuthnTencentCloud inited.");
+ return tfaOptAuthn;
+ }else if(mfaType.equalsIgnoreCase("SmsOtpAuthnYunxin")) {
+ SmsOtpAuthnYunxin tfaOptAuthn = new SmsOtpAuthnYunxin();
+ tfaOptAuthn.initPropertys();
+ _logger.debug("SmsOtpAuthnYunxin inited.");
+ return tfaOptAuthn;
+ }else {
+ TimeBasedOtpAuthn tfaOptAuthn = new TimeBasedOtpAuthn();
+ _logger.debug("TimeBasedOtpAuthn inited.");
+ return tfaOptAuthn;
+ }
}
@Bean(name = "tfaMailOptAuthn")
- public MailOtpAuthn mailOtpAuthn() {
+ public MailOtpAuthn mailOtpAuthn(
+ @Value("${spring.mail.properties.mailotp.message.subject}")
+ String messageSubject,
+ @Value("${spring.mail.properties.mailotp.message.template}")
+ String messageTemplate
+ ) {
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn();
+ mailOtpAuthn.setSubject(messageSubject);
+ mailOtpAuthn.setMessageTemplate(messageTemplate);
_logger.debug("tfaMailOptAuthn inited.");
return mailOtpAuthn;
}
@Bean(name = "tfaMobileOptAuthn")
- public SmsOtpAuthn smsOtpAuthn() {
- SmsOtpAuthnYunxin smsOtpAuthn = new SmsOtpAuthnYunxin();
+ public SmsOtpAuthn smsOtpAuthn(@Value("${config.otp.sms}")String optSmsProvider) {
+ SmsOtpAuthn smsOtpAuthn = null;
+
+ if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
+ smsOtpAuthn = new SmsOtpAuthnAliyun();
+ }else if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnTencentCloud")) {
+ smsOtpAuthn = new SmsOtpAuthnTencentCloud();
+ }else {
+ smsOtpAuthn = new SmsOtpAuthnYunxin();
+ }
+ smsOtpAuthn.initPropertys();
+
_logger.debug("SmsOtpAuthn inited.");
return smsOtpAuthn;
}
+
@Bean(name = "kerberosService")
public RemoteKerberosService kerberosService(
@Value("${config.support.kerberos.default.userdomain}")
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
index 6753d0c1e..6375c6223 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
@@ -128,8 +128,8 @@ public class LoginEndpoint {
if(!isAuthenticated){
modelAndView.addObject("isRemeberMe", applicationConfig.getLoginConfig().isRemeberMe());
modelAndView.addObject("isKerberos", applicationConfig.getLoginConfig().isKerberos());
- modelAndView.addObject("isOneTimePwd", applicationConfig.getLoginConfig().isOneTimePwd());
- if(applicationConfig.getLoginConfig().isOneTimePwd()) {
+ modelAndView.addObject("isMfa", applicationConfig.getLoginConfig().isMfa());
+ if(applicationConfig.getLoginConfig().isMfa()) {
modelAndView.addObject("optType", tfaOptAuthn.getOptType());
modelAndView.addObject("optInterval", tfaOptAuthn.getInterval());
}
diff --git a/maxkey-web-maxkey/src/main/resources/application.properties b/maxkey-web-maxkey/src/main/resources/application.properties
index 4234f0a91..5ee428d89 100644
--- a/maxkey-web-maxkey/src/main/resources/application.properties
+++ b/maxkey-web-maxkey/src/main/resources/application.properties
@@ -49,6 +49,8 @@ spring.mail.password=password
spring.mail.protocol=smtp
spring.mail.properties.ssl=true
spring.mail.properties.sender=maxkey@163.com
+spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
+spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
#for freemarker
spring.freemarker.template-loader-path=classpath:/templates/views
spring.freemarker.cache=false
diff --git a/maxkey-web-maxkey/src/main/resources/maxkey.properties b/maxkey-web-maxkey/src/main/resources/maxkey.properties
index 47b214ae3..d6f3ae6cd 100644
--- a/maxkey-web-maxkey/src/main/resources/maxkey.properties
+++ b/maxkey-web-maxkey/src/main/resources/maxkey.properties
@@ -19,7 +19,9 @@ config.login.captcha=true
#text or arithmetic
config.login.captcha.type=text
#enable two factor,use one time password
-config.login.onetimepwd=true
+config.login.mfa=true
+#TimeBasedOtpAuthn MailOtpAuthn SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
+config.login.mfa.type=TimeBasedOtpAuthn
#enable social sign on
config.login.socialsignon=true
#social sign on providers
@@ -38,6 +40,24 @@ config.login.default.uri=appList
config.ipaddress.whitelist=false
+#SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
+config.otp.sms=SmsOtpAuthnYunxin
+
+config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.aliyun.accesssecret=05d5485357bc
+config.otp.sms.aliyun.templatecode=14860095
+config.otp.sms.aliyun.signname=maxkey
+
+config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.yunxin.appsecret=05d5485357bc
+config.otp.sms.yunxin.templateid=14860095
+
+config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
+config.otp.sms.tencentcloud.secretkey=05d5485357bc
+config.otp.sms.tencentcloud.smssdkappid=1486220095
+config.otp.sms.tencentcloud.templateid=14860095
+config.otp.sms.tencentcloud.sign=1486009522
+
config.otp.keyuri.format.type=totp
config.otp.keyuri.format.digits=6
config.otp.keyuri.format.issuer=MaxKey
diff --git a/maxkey-web-maxkey/src/main/resources/templates/views/login.ftl b/maxkey-web-maxkey/src/main/resources/templates/views/login.ftl
index b280a4396..d07b5fb64 100644
--- a/maxkey-web-maxkey/src/main/resources/templates/views/login.ftl
+++ b/maxkey-web-maxkey/src/main/resources/templates/views/login.ftl
@@ -54,7 +54,7 @@ function formatTime(){
strTime+=(seconds<10?"0"+seconds:seconds);
}
-<#if true==isOneTimePwd && "TOPT"==optType>
+<#if true==isMfa && "TOPT"==optType>
function currentTime(){
seconds++;
if(seconds>59){
@@ -119,7 +119,7 @@ document.onkeydown=function(event){
};
$(function(){
- <#if true==isOneTimePwd && "TOPT"==optType>
+ <#if true==isMfa && "TOPT"==optType>
setInterval("currentTime()", 1000);
#if>
<#--on captcha image click ,new a captcha code-->
@@ -261,7 +261,7 @@ $(function(){
<@locale code="login.text.password"/>:
- <#if true==isOneTimePwd >
+ <#if true==isMfa >
<#if "TOPT"==optType >
<@locale code="login.text.currenttime"/>: