MFA Enhance

MFA  Enhance
This commit is contained in:
shimingxy 2020-05-31 12:13:15 +08:00
parent 1c0ea6ce7e
commit 4b197b9c33
13 changed files with 241 additions and 126 deletions

View File

@ -27,10 +27,17 @@
2、电子邮件 2、电子邮件
<h2>短信验证码</h2> <h2>短信认证</h2>
配置maxkey中maxkey.properties
<pre><code class="ini hljs">
#SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
config.otp.sms=SmsOtpAuthnYunxin
</code></pre>
<h3>腾讯云短信</h3> <h3>腾讯云短信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
secretId 账号Appkey secretId 账号Appkey
secretKey 密钥appSecret secretKey 密钥appSecret
@ -41,19 +48,15 @@ templateId 短信模板ID
sign 签名 sign 签名
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud"&gt; config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
&lt;property name="secretId" value="94395d754eb55693043f5d6a2b772ef4" /&gt; config.otp.sms.aliyun.accesssecret=05d5485357bc
&lt;property name="secretKey" value="05d5485357bc" /&gt; config.otp.sms.aliyun.templatecode=14860095
&lt;property name="smsSdkAppid" value="1486220095" /&gt; config.otp.sms.aliyun.signname=maxkey
&lt;property name="templateId" value="14860095" /&gt;
&lt;property name="sign" value="1486009522" /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>
<h3>阿里云短信</h3> <h3>阿里云短信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
accessKeyId 账号Appkey accessKeyId 账号Appkey
@ -63,18 +66,16 @@ templateCode 短信模板ID
signName 签名 signName 签名
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun"&gt; config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
&lt;property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" /&gt; config.otp.sms.tencentcloud.secretkey=05d5485357bc
&lt;property name="accessSecret" value="05d5485357bc" /&gt; config.otp.sms.tencentcloud.smssdkappid=1486220095
&lt;property name="templateCode" value="SMS_187590021" /&gt; config.otp.sms.tencentcloud.templateid=14860095
&lt;property name="signName" value="MaxKey" /&gt; config.otp.sms.tencentcloud.sign=1486009522
&lt;/bean&gt;
</code></pre> </code></pre>
<h3>网易云信</h3> <h3>网易云信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
appKey 网易云信分配的账号Appkey appKey 网易云信分配的账号Appkey
@ -82,13 +83,10 @@ appSecret 网易云信分配的密钥appSecret
templateId 短信模板ID templateId 短信模板ID
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin"&gt; config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
&lt;property name="appKey" value="94395d754eb55693043f5d6a2b772ef4" /&gt; config.otp.sms.yunxin.appsecret=05d5485357bc
&lt;property name="appSecret" value="05d5485357bc" /&gt; config.otp.sms.yunxin.templateid=14860095
&lt;property name="templateId" value="14860095" /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>
<h2>电子邮件</h2> <h2>电子邮件</h2>
@ -96,28 +94,26 @@ templateId 短信模板ID
配置邮箱地址 配置邮箱地址
文件 文件
maxkey/config/applicationConfig.properties maxkey/application.properties
<pre><code class="ini hljs"> <pre><code class="ini hljs">
# EMAIL configuration spring.mail.default-encoding=utf-8
config.email.username=maxkey@163.com spring.mail.host=smtp.163.com
config.email.password=password spring.mail.port=465
config.email.smtpHost=smtp.163.com spring.mail.username=maxkey@163.com
config.email.port=465 spring.mail.password=password
config.email.senderMail=maxkey@163.com spring.mail.protocol=smtp
config.email.ssl=true spring.mail.properties.ssl=true
spring.mail.properties.sender=maxkey@163.com
</code></pre> </code></pre>
配置maxkey中spring/maxkey-security.xml 配置maxkey中application.properties
subject 邮件主题 subject 邮件主题
messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔 messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔
<pre><code class="xml hljs"> <pre><code class="ini hljs">
spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
&lt;bean id="tfaMailOptAuthn" class="org.maxkey.crypto.password.opt.impl.MailOtpAuthn"&gt; spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
&lt;property name="subject" value="MaxKey One Time PassWord" /&gt;
&lt;property name="messageTemplate" value="{0} You Token is {1} , it validity in {2} minutes." /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>

View File

@ -14,8 +14,16 @@
<h2>短信认证</h2> <h2>短信认证</h2>
配置maxkey中maxkey.properties
<pre><code class="ini hljs">
config.login.mfa=true
#TimeBasedOtpAuthn MailOtpAuthn SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
config.login.mfa.type=TimeBasedOtpAuthn
</code></pre>
<h3>腾讯云短信</h3> <h3>腾讯云短信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
secretId 账号Appkey secretId 账号Appkey
secretKey 密钥appSecret secretKey 密钥appSecret
@ -26,23 +34,15 @@ templateId 短信模板ID
sign 签名 sign 签名
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;!-- config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn"&gt; config.otp.sms.aliyun.accesssecret=05d5485357bc
&lt;/bean&gt; config.otp.sms.aliyun.templatecode=14860095
--&gt; config.otp.sms.aliyun.signname=maxkey
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud"&gt;
&lt;property name="secretId" value="94395d754eb55693043f5d6a2b772ef4" /&gt;
&lt;property name="secretKey" value="05d5485357bc" /&gt;
&lt;property name="smsSdkAppid" value="1486220095" /&gt;
&lt;property name="templateId" value="14860095" /&gt;
&lt;property name="sign" value="1486009522" /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>
<h3>阿里云短信</h3> <h3>阿里云短信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
accessKeyId 账号Appkey accessKeyId 账号Appkey
@ -52,22 +52,16 @@ templateCode 短信模板ID
signName 签名 signName 签名
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;!-- config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn"&gt; config.otp.sms.tencentcloud.secretkey=05d5485357bc
&lt;/bean&gt; config.otp.sms.tencentcloud.smssdkappid=1486220095
--&gt; config.otp.sms.tencentcloud.templateid=14860095
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun"&gt; config.otp.sms.tencentcloud.sign=1486009522
&lt;property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" /&gt;
&lt;property name="accessSecret" value="05d5485357bc" /&gt;
&lt;property name="templateCode" value="SMS_187590021" /&gt;
&lt;property name="signName" value="MaxKey" /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>
<h3>网易云信</h3> <h3>网易云信</h3>
配置maxkey中spring/maxkey-security.xml 配置maxkey中maxkey.properties
appKey 网易云信分配的账号Appkey appKey 网易云信分配的账号Appkey
@ -75,17 +69,10 @@ appSecret 网易云信分配的密钥appSecret
templateId 短信模板ID templateId 短信模板ID
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;!-- config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn"&gt; config.otp.sms.yunxin.appsecret=05d5485357bc
&lt;/bean&gt; config.otp.sms.yunxin.templateid=14860095
--&gt;
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin"&gt;
&lt;property name="appKey" value="94395d754eb55693043f5d6a2b772ef4" /&gt;
&lt;property name="appSecret" value="05d5485357bc" /&gt;
&lt;property name="templateId" value="14860095" /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>
<h2>电子邮件</h2> <h2>电子邮件</h2>
@ -93,31 +80,27 @@ templateId 短信模板ID
配置邮箱地址 配置邮箱地址
文件 文件
maxkey/config/applicationConfig.properties maxkey/application.properties
<pre><code class="ini hljs"> <pre><code class="ini hljs">
# EMAIL configuration # EMAIL configuration
config.email.username=maxkey@163.com spring.mail.default-encoding=utf-8
config.email.password=password spring.mail.host=smtp.163.com
config.email.smtpHost=smtp.163.com spring.mail.port=465
config.email.port=465 spring.mail.username=maxkey@163.com
config.email.senderMail=maxkey@163.com spring.mail.password=password
config.email.ssl=true spring.mail.protocol=smtp
spring.mail.properties.ssl=true
spring.mail.properties.sender=maxkey@163.com
</code></pre> </code></pre>
配置maxkey中spring/maxkey-security.xml 配置maxkey中application.properties
subject 邮件主题 subject 邮件主题
messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔 messageTemplate 邮件内容模板,请勿修改参数{0}为用户名,{1}认证码,{2}有效间隔
<pre><code class="xml hljs"> <pre><code class="ini hljs">
&lt;!-- spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn"&gt; spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
&lt;/bean&gt;
--&gt;
&lt;bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.MailOtpAuthn"&gt;
&lt;property name="subject" value="MaxKey One Time PassWord" /&gt;
&lt;property name="messageTemplate" value="{0} You Token is {1} , it validity in {2} minutes." /&gt;
&lt;/bean&gt;
</code></pre> </code></pre>

View File

@ -188,7 +188,7 @@ public abstract class AbstractAuthenticationProvider {
*/ */
protected void tftcaptchaValid(String otpCaptcha, String authType, UserInfo userInfo) { protected void tftcaptchaValid(String otpCaptcha, String authType, UserInfo userInfo) {
// for one time password 2 factor // for one time password 2 factor
if (applicationConfig.getLoginConfig().isOneTimePwd() && authType.equalsIgnoreCase("tfa")) { if (applicationConfig.getLoginConfig().isMfa() && authType.equalsIgnoreCase("tfa")) {
UserInfo validUserInfo = new UserInfo(); UserInfo validUserInfo = new UserInfo();
validUserInfo.setUsername(userInfo.getUsername()); validUserInfo.setUsername(userInfo.getUsername());
String sharedSecret = String sharedSecret =

View File

@ -15,8 +15,8 @@ public class LoginConfig {
@Value("${config.login.captcha.type:text}") @Value("${config.login.captcha.type:text}")
String captchaType; String captchaType;
@Value("${config.login.onetimepwd}") @Value("${config.login.mfa}")
boolean oneTimePwd; boolean mfa;
@Value("${config.login.socialsignon}") @Value("${config.login.socialsignon}")
boolean socialSignOn; boolean socialSignOn;
@ -48,14 +48,6 @@ public class LoginConfig {
this.captcha = captcha; this.captcha = captcha;
} }
public boolean isOneTimePwd() {
return oneTimePwd;
}
public void setOneTimePwd(boolean oneTimePwd) {
this.oneTimePwd = oneTimePwd;
}
public boolean isSocialSignOn() { public boolean isSocialSignOn() {
return socialSignOn; return socialSignOn;
} }
@ -72,6 +64,14 @@ public class LoginConfig {
this.kerberos = kerberos; this.kerberos = kerberos;
} }
public boolean isMfa() {
return mfa;
}
public void setMfa(boolean mfa) {
this.mfa = mfa;
}
public String getDefaultUri() { public String getDefaultUri() {
return defaultUri; return defaultUri;
} }
@ -109,7 +109,7 @@ public class LoginConfig {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder builder
.append("LoginConfig [captcha=").append(captcha) .append("LoginConfig [captcha=").append(captcha)
.append(", oneTimePwd=").append(oneTimePwd) .append(", mfa=").append(mfa)
.append(", socialSignOn=").append(socialSignOn) .append(", socialSignOn=").append(socialSignOn)
.append(", kerberos=").append(kerberos) .append(", kerberos=").append(kerberos)
.append(", remeberMe=").append(remeberMe) .append(", remeberMe=").append(remeberMe)

View File

@ -1,15 +1,26 @@
package org.maxkey.crypto.password.opt.impl; 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.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo; 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 { public class SmsOtpAuthn extends AbstractOptAuthn {
private static final Logger logger = LoggerFactory.getLogger(SmsOtpAuthn.class);
protected Properties properties;
@Override @Override
public boolean produce(UserInfo userInfo) { public boolean produce(UserInfo userInfo) {
String token = this.genToken(userInfo); String token = this.genToken(userInfo);
// TODO:You must add send sms code here // TODO:You must add send sms code here
logger.debug("send sms code" + token);
return true; return true;
} }
@ -17,5 +28,18 @@ public class SmsOtpAuthn extends AbstractOptAuthn {
public boolean validate(UserInfo userInfo, String token) { public boolean validate(UserInfo userInfo, String token) {
return true; 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() {
}
} }

View File

@ -6,6 +6,9 @@ import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient; import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType; import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.DefaultProfile;
import java.io.IOException;
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn; import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.domain.UserInfo; import org.maxkey.domain.UserInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -110,4 +113,18 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
this.signName = signName; 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");
}
} }

View File

@ -6,6 +6,9 @@ import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient; import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import java.io.IOException;
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn; import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.domain.UserInfo; import org.maxkey.domain.UserInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -153,4 +156,19 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
this.sign = sign; 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");
}
} }

View File

@ -1,5 +1,6 @@
package org.maxkey.crypto.password.opt.impl.sms; package org.maxkey.crypto.password.opt.impl.sms;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; 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. * main.
* @param args String * @param args String

View File

@ -16,10 +16,13 @@ import org.maxkey.authn.support.kerberos.KerberosProxy;
import org.maxkey.authn.support.kerberos.RemoteKerberosService; import org.maxkey.authn.support.kerberos.RemoteKerberosService;
import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter; import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter;
import org.maxkey.constants.ConstantsProperties; 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.algorithm.KeyUriFormat;
import org.maxkey.crypto.password.opt.impl.MailOtpAuthn; import org.maxkey.crypto.password.opt.impl.MailOtpAuthn;
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn; import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
import org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn; 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.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils; import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils; import org.maxkey.persistence.ldap.LdapUtils;
@ -180,27 +183,65 @@ public class MaxKeyConfig implements InitializingBean {
return authenticationRealm; return authenticationRealm;
} }
//default tfaOptAuthn
@Bean(name = "tfaOptAuthn") @Bean(name = "tfaOptAuthn")
public TimeBasedOtpAuthn tfaOptAuthn() { public AbstractOptAuthn tfaOptAuthn(
TimeBasedOtpAuthn tfaOptAuthn = new TimeBasedOtpAuthn(); @Value("${config.login.mfa.type}")String mfaType) {
_logger.debug("TimeBasedOtpAuthn inited.");
return tfaOptAuthn; 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") @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 mailOtpAuthn = new MailOtpAuthn();
mailOtpAuthn.setSubject(messageSubject);
mailOtpAuthn.setMessageTemplate(messageTemplate);
_logger.debug("tfaMailOptAuthn inited."); _logger.debug("tfaMailOptAuthn inited.");
return mailOtpAuthn; return mailOtpAuthn;
} }
@Bean(name = "tfaMobileOptAuthn") @Bean(name = "tfaMobileOptAuthn")
public SmsOtpAuthn smsOtpAuthn() { public SmsOtpAuthn smsOtpAuthn(@Value("${config.otp.sms}")String optSmsProvider) {
SmsOtpAuthnYunxin smsOtpAuthn = new SmsOtpAuthnYunxin(); 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."); _logger.debug("SmsOtpAuthn inited.");
return smsOtpAuthn; return smsOtpAuthn;
} }
@Bean(name = "kerberosService") @Bean(name = "kerberosService")
public RemoteKerberosService kerberosService( public RemoteKerberosService kerberosService(
@Value("${config.support.kerberos.default.userdomain}") @Value("${config.support.kerberos.default.userdomain}")

View File

@ -128,8 +128,8 @@ public class LoginEndpoint {
if(!isAuthenticated){ if(!isAuthenticated){
modelAndView.addObject("isRemeberMe", applicationConfig.getLoginConfig().isRemeberMe()); modelAndView.addObject("isRemeberMe", applicationConfig.getLoginConfig().isRemeberMe());
modelAndView.addObject("isKerberos", applicationConfig.getLoginConfig().isKerberos()); modelAndView.addObject("isKerberos", applicationConfig.getLoginConfig().isKerberos());
modelAndView.addObject("isOneTimePwd", applicationConfig.getLoginConfig().isOneTimePwd()); modelAndView.addObject("isMfa", applicationConfig.getLoginConfig().isMfa());
if(applicationConfig.getLoginConfig().isOneTimePwd()) { if(applicationConfig.getLoginConfig().isMfa()) {
modelAndView.addObject("optType", tfaOptAuthn.getOptType()); modelAndView.addObject("optType", tfaOptAuthn.getOptType());
modelAndView.addObject("optInterval", tfaOptAuthn.getInterval()); modelAndView.addObject("optInterval", tfaOptAuthn.getInterval());
} }

View File

@ -49,6 +49,8 @@ spring.mail.password=password
spring.mail.protocol=smtp spring.mail.protocol=smtp
spring.mail.properties.ssl=true spring.mail.properties.ssl=true
spring.mail.properties.sender=maxkey@163.com 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 #for freemarker
spring.freemarker.template-loader-path=classpath:/templates/views spring.freemarker.template-loader-path=classpath:/templates/views
spring.freemarker.cache=false spring.freemarker.cache=false

View File

@ -19,7 +19,9 @@ config.login.captcha=true
#text or arithmetic #text or arithmetic
config.login.captcha.type=text config.login.captcha.type=text
#enable two factor,use one time password #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 #enable social sign on
config.login.socialsignon=true config.login.socialsignon=true
#social sign on providers #social sign on providers
@ -38,6 +40,24 @@ config.login.default.uri=appList
config.ipaddress.whitelist=false 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.type=totp
config.otp.keyuri.format.digits=6 config.otp.keyuri.format.digits=6
config.otp.keyuri.format.issuer=MaxKey config.otp.keyuri.format.issuer=MaxKey

View File

@ -54,7 +54,7 @@ function formatTime(){
strTime+=(seconds<10?"0"+seconds:seconds); strTime+=(seconds<10?"0"+seconds:seconds);
} }
<#if true==isOneTimePwd && "TOPT"==optType> <#if true==isMfa && "TOPT"==optType>
function currentTime(){ function currentTime(){
seconds++; seconds++;
if(seconds>59){ if(seconds>59){
@ -119,7 +119,7 @@ document.onkeydown=function(event){
}; };
$(function(){ $(function(){
<#if true==isOneTimePwd && "TOPT"==optType> <#if true==isMfa && "TOPT"==optType>
setInterval("currentTime()", 1000); setInterval("currentTime()", 1000);
</#if> </#if>
<#--on captcha image click ,new a captcha code--> <#--on captcha image click ,new a captcha code-->
@ -261,7 +261,7 @@ $(function(){
<td><@locale code="login.text.password"/></td> <td><@locale code="login.text.password"/></td>
<td><input required="" class="form-control" type='password' id='tfa_j_password' name='password' value="" tabindex="2" /></td> <td><input required="" class="form-control" type='password' id='tfa_j_password' name='password' value="" tabindex="2" /></td>
</tr> </tr>
<#if true==isOneTimePwd > <#if true==isMfa >
<#if "TOPT"==optType > <#if "TOPT"==optType >
<tr> <tr>
<td><@locale code="login.text.currenttime"/></td> <td><@locale code="login.text.currenttime"/></td>