mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-08 01:48:33 +08:00
MFA Enhance
MFA Enhance
This commit is contained in:
parent
1c0ea6ce7e
commit
4b197b9c33
@ -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">
|
||||||
<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnTencentCloud">
|
config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
|
||||||
<property name="secretId" value="94395d754eb55693043f5d6a2b772ef4" />
|
config.otp.sms.aliyun.accesssecret=05d5485357bc
|
||||||
<property name="secretKey" value="05d5485357bc" />
|
config.otp.sms.aliyun.templatecode=14860095
|
||||||
<property name="smsSdkAppid" value="1486220095" />
|
config.otp.sms.aliyun.signname=maxkey
|
||||||
<property name="templateId" value="14860095" />
|
|
||||||
<property name="sign" value="1486009522" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</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">
|
||||||
<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun">
|
config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
|
||||||
<property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" />
|
config.otp.sms.tencentcloud.secretkey=05d5485357bc
|
||||||
<property name="accessSecret" value="05d5485357bc" />
|
config.otp.sms.tencentcloud.smssdkappid=1486220095
|
||||||
<property name="templateCode" value="SMS_187590021" />
|
config.otp.sms.tencentcloud.templateid=14860095
|
||||||
<property name="signName" value="MaxKey" />
|
config.otp.sms.tencentcloud.sign=1486009522
|
||||||
</bean>
|
|
||||||
|
|
||||||
</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">
|
||||||
<bean id="tfaMobileOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnYunxin">
|
config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
|
||||||
<property name="appKey" value="94395d754eb55693043f5d6a2b772ef4" />
|
config.otp.sms.yunxin.appsecret=05d5485357bc
|
||||||
<property name="appSecret" value="05d5485357bc" />
|
config.otp.sms.yunxin.templateid=14860095
|
||||||
<property name="templateId" value="14860095" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</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
|
||||||
<bean id="tfaMailOptAuthn" class="org.maxkey.crypto.password.opt.impl.MailOtpAuthn">
|
spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
|
||||||
<property name="subject" value="MaxKey One Time PassWord" />
|
|
||||||
<property name="messageTemplate" value="{0} You Token is {1} , it validity in {2} minutes." />
|
|
||||||
</bean>
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -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">
|
||||||
<!--
|
config.otp.sms.aliyun.accesskeyid=94395d754eb55693043f5d6a2b772ef4
|
||||||
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
|
config.otp.sms.aliyun.accesssecret=05d5485357bc
|
||||||
</bean>
|
config.otp.sms.aliyun.templatecode=14860095
|
||||||
-->
|
config.otp.sms.aliyun.signname=maxkey
|
||||||
<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>
|
|
||||||
|
|
||||||
</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">
|
||||||
<!--
|
config.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
|
||||||
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
|
config.otp.sms.tencentcloud.secretkey=05d5485357bc
|
||||||
</bean>
|
config.otp.sms.tencentcloud.smssdkappid=1486220095
|
||||||
-->
|
config.otp.sms.tencentcloud.templateid=14860095
|
||||||
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.sms.SmsOtpAuthnAliyun">
|
config.otp.sms.tencentcloud.sign=1486009522
|
||||||
<property name="accessKeyId" value="94395d754eb55693043f5d6a2b772ef3" />
|
|
||||||
<property name="accessSecret" value="05d5485357bc" />
|
|
||||||
<property name="templateCode" value="SMS_187590021" />
|
|
||||||
<property name="signName" value="MaxKey" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</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">
|
||||||
<!--
|
config.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
|
||||||
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
|
config.otp.sms.yunxin.appsecret=05d5485357bc
|
||||||
</bean>
|
config.otp.sms.yunxin.templateid=14860095
|
||||||
-->
|
|
||||||
<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>
|
|
||||||
|
|
||||||
</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">
|
||||||
<!--
|
spring.mail.properties.mailotp.message.subject=MaxKey One Time PassWord
|
||||||
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
|
spring.mail.properties.mailotp.message.template={0} You Token is {1} , it validity in {2} minutes.
|
||||||
</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>
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -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 =
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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}")
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user