mirror of
https://gitee.com/dromara/MaxKey.git
synced 2026-05-14 12:32:09 +08:00
http
This commit is contained in:
@@ -17,9 +17,13 @@
|
||||
|
||||
package org.maxkey;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm;
|
||||
import org.maxkey.authn.realm.ldap.LdapAuthenticationRealm;
|
||||
@@ -31,6 +35,7 @@ import org.maxkey.authn.realm.activedirectory.ActiveDirectoryServer;
|
||||
import org.maxkey.authn.support.kerberos.KerberosProxy;
|
||||
import org.maxkey.authn.support.kerberos.RemoteKerberosService;
|
||||
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
|
||||
import org.maxkey.configuration.EmailConfig;
|
||||
import org.maxkey.constants.ConstantsPersistence;
|
||||
import org.maxkey.constants.ConstantsProperties;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
@@ -57,6 +62,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@@ -216,14 +223,32 @@ public class MaxKeyConfig implements InitializingBean {
|
||||
|
||||
@Bean(name = "mailOtpAuthn")
|
||||
public MailOtpAuthn mailOtpAuthn(
|
||||
EmailConfig emailConfig,
|
||||
@Value("${spring.mail.properties.mailotp.message.subject}")
|
||||
String messageSubject,
|
||||
@Value("${spring.mail.properties.mailotp.message.template}")
|
||||
String messageTemplate
|
||||
String messageTemplate,
|
||||
@Value("${spring.mail.properties.mailotp.message.validity}")
|
||||
int messageValidity,
|
||||
@Value("${spring.mail.properties.mailotp.message.type}")
|
||||
String messageType
|
||||
) {
|
||||
if(messageType!= null && messageType.equalsIgnoreCase("html")) {
|
||||
Resource resource = new ClassPathResource("messages/email/forgotpassword.html");
|
||||
try {
|
||||
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(resource.getInputStream()));
|
||||
messageTemplate = bufferedReader.lines().collect(Collectors.joining("\n"));
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
_logger.error("mailOtpAuthn IOException ",e);
|
||||
}
|
||||
}
|
||||
_logger.trace("messageTemplate \n" +messageTemplate);
|
||||
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn();
|
||||
mailOtpAuthn.setSubject(messageSubject);
|
||||
mailOtpAuthn.setMessageTemplate(messageTemplate);
|
||||
mailOtpAuthn.setEmailConfig(emailConfig);
|
||||
mailOtpAuthn.setInterval(messageValidity);
|
||||
_logger.debug("MailOtpAuthn inited.");
|
||||
return mailOtpAuthn;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
package org.maxkey.web.contorller;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.maxkey.configuration.EmailConfig;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.persistence.db.PasswordPolicyValidator;
|
||||
import org.maxkey.persistence.service.UserInfoService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
@@ -45,6 +46,9 @@ public class ForgotPasswordContorller {
|
||||
Pattern mobileRegex = Pattern.compile(
|
||||
"^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\\\d{8}$");
|
||||
|
||||
@Autowired
|
||||
EmailConfig emailConfig;
|
||||
|
||||
public class ForgotType{
|
||||
public final static int NOTFOUND = 1;
|
||||
public final static int EMAIL = 2;
|
||||
@@ -84,16 +88,24 @@ public class ForgotPasswordContorller {
|
||||
UserInfo userInfo = null;
|
||||
if (captcha != null && captcha
|
||||
.equals(WebContext.getSession().getAttribute(
|
||||
WebConstants.KAPTCHA_SESSION_KEY).toString())) {
|
||||
WebConstants.KAPTCHA_SESSION_KEY).toString())) {
|
||||
if(mobileRegex.matcher(emailMobile).matches()) {
|
||||
forgotType = ForgotType.MOBILE;
|
||||
}else if(emailRegex.matcher(emailMobile).matches()) {
|
||||
forgotType = ForgotType.EMAIL;
|
||||
}else {
|
||||
forgotType = ForgotType.EMAIL;
|
||||
emailMobile =emailMobile + "@" + emailConfig.getSmtpHost().substring(emailConfig.getSmtpHost().indexOf(".")+1);
|
||||
}
|
||||
|
||||
userInfo = userInfoService.queryUserInfoByEmailMobile(emailMobile);
|
||||
|
||||
Matcher matcher = emailRegex.matcher(emailMobile);
|
||||
if (matcher.matches() && null != userInfo) {
|
||||
mailOtpAuthn.produce(userInfo);
|
||||
forgotType = ForgotType.EMAIL;
|
||||
}else if (null != userInfo) {
|
||||
smsOtpAuthn.produce(userInfo);
|
||||
forgotType = ForgotType.MOBILE;
|
||||
if(null != userInfo) {
|
||||
if (forgotType == ForgotType.EMAIL ) {
|
||||
mailOtpAuthn.produce(userInfo);
|
||||
}else if (forgotType == ForgotType.MOBILE) {
|
||||
smsOtpAuthn.produce(userInfo);
|
||||
}
|
||||
}
|
||||
|
||||
}else {
|
||||
@@ -129,8 +141,13 @@ public class ForgotPasswordContorller {
|
||||
if ((forgotType == ForgotType.EMAIL && mailOtpAuthn.validate(userInfo, captcha)) ||
|
||||
(forgotType == ForgotType.MOBILE && smsOtpAuthn.validate(userInfo, captcha))
|
||||
) {
|
||||
userInfoService.changePassword(userInfo,true);
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
|
||||
if(userInfoService.changePassword(userInfo,true)) {
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
|
||||
}else {
|
||||
;
|
||||
modelAndView.addObject("validate_result", WebContext.getAttribute(PasswordPolicyValidator.PASSWORD_POLICY_VALIDATE_RESULT));
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.PASSWORDERROR);
|
||||
}
|
||||
} else {
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.CAPTCHAERROR);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.apache.mybatis.jpa.persistence.JpaPageResults;
|
||||
import org.maxkey.entity.HistoryLoginApps;
|
||||
import org.maxkey.persistence.service.HistoryLoginAppsService;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -66,7 +67,7 @@ public class HistoryLoginAppsController {
|
||||
@ModelAttribute("historyLoginApps") HistoryLoginApps historyLoginApps) {
|
||||
_logger.debug("history/loginApps/grid/ logsGrid() " + historyLoginApps);
|
||||
historyLoginApps.setId(null);
|
||||
|
||||
historyLoginApps.setUsername(WebContext.getUserInfo().getUsername());
|
||||
return historyLoginAppsService.queryPageResults(historyLoginApps);
|
||||
|
||||
}
|
||||
|
||||
@@ -95,7 +95,8 @@ mybatis.table-column-case=lowercase
|
||||
#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.
|
||||
|
||||
spring.mail.properties.mailotp.message.type=html
|
||||
spring.mail.properties.mailotp.message.validity=300
|
||||
############################################################################
|
||||
#freemarker configuration #
|
||||
############################################################################
|
||||
@@ -139,23 +140,20 @@ spring.session.store-type=none
|
||||
#Kafka for connectors configuration #
|
||||
############################################################################
|
||||
spring.kafka.bootstrap-servers=localhost:9092
|
||||
###########\u3010\u521d\u59cb\u5316\u751f\u4ea7\u8005\u914d\u7f6e\u3011###########
|
||||
# \u91cd\u8bd5\u6b21\u6570
|
||||
# retries
|
||||
spring.kafka.producer.retries=0
|
||||
# \u5e94\u7b54\u7ea7\u522b:\u591a\u5c11\u4e2a\u5206\u533a\u526f\u672c\u5907\u4efd\u5b8c\u6210\u65f6\u5411\u751f\u4ea7\u8005\u53d1\u9001ack\u786e\u8ba4(\u53ef\u90090\u30011\u3001all/-1)
|
||||
# acks
|
||||
spring.kafka.producer.acks=1
|
||||
# \u6279\u91cf\u5927\u5c0f
|
||||
# batch-size
|
||||
spring.kafka.producer.batch-size=16384
|
||||
# \u63d0\u4ea4\u5ef6\u65f6
|
||||
# linger.ms
|
||||
spring.kafka.producer.properties.linger.ms=0
|
||||
# \u5f53\u751f\u4ea7\u7aef\u79ef\u7d2f\u7684\u6d88\u606f\u8fbe\u5230batch-size\u6216\u63a5\u6536\u5230\u6d88\u606flinger.ms\u540e,\u751f\u4ea7\u8005\u5c31\u4f1a\u5c06\u6d88\u606f\u63d0\u4ea4\u7ed9kafka
|
||||
# linger.ms\u4e3a0\u8868\u793a\u6bcf\u63a5\u6536\u5230\u4e00\u6761\u6d88\u606f\u5c31\u63d0\u4ea4\u7ed9kafka,\u8fd9\u65f6\u5019batch-size\u5176\u5b9e\u5c31\u6ca1\u7528\u4e86
|
||||
# \u751f\u4ea7\u7aef\u7f13\u51b2\u533a\u5927\u5c0f
|
||||
# buffer-memory
|
||||
spring.kafka.producer.buffer-memory = 33554432
|
||||
# Kafka\u63d0\u4f9b\u7684\u5e8f\u5217\u5316\u548c\u53cd\u5e8f\u5217\u5316\u7c7b
|
||||
# serializer
|
||||
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
# \u81ea\u5b9a\u4e49\u5206\u533a\u5668
|
||||
# partitioner
|
||||
# spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
|
||||
|
||||
############################################################################
|
||||
|
||||
@@ -95,6 +95,8 @@ mybatis.table-column-case=lowercase
|
||||
#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.
|
||||
spring.mail.properties.mailotp.message.type=html
|
||||
spring.mail.properties.mailotp.message.validity=300
|
||||
|
||||
############################################################################
|
||||
#freemarker configuration #
|
||||
@@ -139,24 +141,21 @@ spring.session.store-type=none
|
||||
#Kafka for connectors configuration #
|
||||
############################################################################
|
||||
spring.kafka.bootstrap-servers=localhost:9092
|
||||
###########\u3010\u521d\u59cb\u5316\u751f\u4ea7\u8005\u914d\u7f6e\u3011###########
|
||||
# \u91cd\u8bd5\u6b21\u6570
|
||||
# retries
|
||||
spring.kafka.producer.retries=0
|
||||
# \u5e94\u7b54\u7ea7\u522b:\u591a\u5c11\u4e2a\u5206\u533a\u526f\u672c\u5907\u4efd\u5b8c\u6210\u65f6\u5411\u751f\u4ea7\u8005\u53d1\u9001ack\u786e\u8ba4(\u53ef\u90090\u30011\u3001all/-1)
|
||||
# acks
|
||||
spring.kafka.producer.acks=1
|
||||
# \u6279\u91cf\u5927\u5c0f
|
||||
# batch-size
|
||||
spring.kafka.producer.batch-size=16384
|
||||
# \u63d0\u4ea4\u5ef6\u65f6
|
||||
# linger.ms
|
||||
spring.kafka.producer.properties.linger.ms=0
|
||||
# \u5f53\u751f\u4ea7\u7aef\u79ef\u7d2f\u7684\u6d88\u606f\u8fbe\u5230batch-size\u6216\u63a5\u6536\u5230\u6d88\u606flinger.ms\u540e,\u751f\u4ea7\u8005\u5c31\u4f1a\u5c06\u6d88\u606f\u63d0\u4ea4\u7ed9kafka
|
||||
# linger.ms\u4e3a0\u8868\u793a\u6bcf\u63a5\u6536\u5230\u4e00\u6761\u6d88\u606f\u5c31\u63d0\u4ea4\u7ed9kafka,\u8fd9\u65f6\u5019batch-size\u5176\u5b9e\u5c31\u6ca1\u7528\u4e86
|
||||
# \u751f\u4ea7\u7aef\u7f13\u51b2\u533a\u5927\u5c0f
|
||||
# buffer-memory
|
||||
spring.kafka.producer.buffer-memory = 33554432
|
||||
# Kafka\u63d0\u4f9b\u7684\u5e8f\u5217\u5316\u548c\u53cd\u5e8f\u5217\u5316\u7c7b
|
||||
# serializer
|
||||
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
# \u81ea\u5b9a\u4e49\u5206\u533a\u5668
|
||||
# spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
|
||||
# partitioner
|
||||
#spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
|
||||
|
||||
############################################################################
|
||||
#Management endpoints configuration #
|
||||
@@ -366,7 +365,7 @@ maxkey.socialsignon.wechatopen.sortorder=2
|
||||
#work weixin
|
||||
maxkey.socialsignon.workweixin.provider=workweixin
|
||||
maxkey.socialsignon.workweixin.provider.name=\u4F01\u4E1A\u5fae\u4fe1
|
||||
maxkey.socialsignon.workweixin.icon=images/social/wechat.png
|
||||
maxkey.socialsignon.workweixin.icon=images/social/wechat_enterprise.png
|
||||
maxkey.socialsignon.workweixin.client.id=wx00d052e8f417f8f9
|
||||
maxkey.socialsignon.workweixin.client.secret=lIy40iP0z4D65eJaWDNoe-vSlttmqY2WGJBygbM0TlY
|
||||
maxkey.socialsignon.workweixin.agent.id=1000002
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
尊敬的用户{0}:<br>
|
||||
请复制下面的验证码,并返回页面提交以继续之前的步骤。 <br>
|
||||
<p><b>{1}</b></p>
|
||||
有效期为{2}分钟.<br>
|
||||
如果您没有申请发送该邮件,请忽略。
|
||||
@@ -218,8 +218,12 @@ button.text.expandsearch=\u5c55\u5f00
|
||||
button.text.collapsesearch=\u6536\u7f29
|
||||
|
||||
forgotpassword.emailmobile=\u90ae\u7bb1\u6216\u624b\u673a
|
||||
forgotpassword.email=\u90ae\u7bb1
|
||||
forgotpassword.mobile=\u624b\u673a
|
||||
forgotpassword.nextstep=\u4e0b\u4e00\u6b65
|
||||
forgotpassword.resetpwd.notfound.prefix=\u90ae\u7bb1\u6216\u624b\u673a\u53f7
|
||||
forgotpassword.resetpwd.notfound.prefix.email=\u90ae\u7bb1
|
||||
forgotpassword.resetpwd.notfound.prefix.mobile=\u624b\u673a\u53f7
|
||||
forgotpassword.resetpwd.notfound.suffix=\u4e0d\u5b58\u5728,\u8bf7
|
||||
forgotpassword.backstep=\u91cd\u65b0\u8f93\u5165
|
||||
forgotpassword.pwdreseted.password=\u8f93\u5165\u5bc6\u7801\u6216\u786e\u8ba4\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7
|
||||
|
||||
@@ -217,8 +217,12 @@ button.text.expandsearch=Expand
|
||||
button.text.collapsesearch=Collapse
|
||||
|
||||
forgotpassword.emailmobile=Email OR Mobile
|
||||
forgotpassword.email=Email
|
||||
forgotpassword.mobile=Mobile
|
||||
forgotpassword.nextstep=Next
|
||||
forgotpassword.resetpwd.notfound.prefix=Email OR Mobile
|
||||
forgotpassword.resetpwd.notfound.prefix.email=Email
|
||||
forgotpassword.resetpwd.notfound.prefix.mobile=Mobile
|
||||
forgotpassword.resetpwd.notfound.suffix=not found,pls
|
||||
forgotpassword.backstep=Retry
|
||||
forgotpassword.pwdreseted.password=password error or password not eq the confirm password,pls
|
||||
|
||||
@@ -218,8 +218,12 @@ button.text.expandsearch=\u5c55\u5f00
|
||||
button.text.collapsesearch=\u6536\u7f29
|
||||
|
||||
forgotpassword.emailmobile=\u90ae\u7bb1\u6216\u624b\u673a
|
||||
forgotpassword.email=\u90ae\u7bb1
|
||||
forgotpassword.mobile=\u624b\u673a
|
||||
forgotpassword.nextstep=\u4e0b\u4e00\u6b65
|
||||
forgotpassword.resetpwd.notfound.prefix=\u90ae\u7bb1\u6216\u624b\u673a\u53f7
|
||||
forgotpassword.resetpwd.notfound.prefix.email=\u90ae\u7bb1
|
||||
forgotpassword.resetpwd.notfound.prefix.mobile=\u624b\u673a\u53f7
|
||||
forgotpassword.resetpwd.notfound.suffix=\u4e0d\u5b58\u5728,\u8bf7
|
||||
forgotpassword.backstep=\u91cd\u65b0\u8f93\u5165
|
||||
forgotpassword.pwdreseted.password=\u8f93\u5165\u5bc6\u7801\u6216\u786e\u8ba4\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
<div class="col-md-8">
|
||||
<#if 3 == passwordResetResult>
|
||||
<@locale code="forgotpassword.pwdreseted.password"/>
|
||||
<a href="javascript:history.go(-1);"><@locale code="forgotpassword.backstep"/></a >
|
||||
<a href="<@base/>/forgotpassword/forward"><@locale code="forgotpassword.backstep"/></a >
|
||||
<br>${validate_result}
|
||||
|
||||
</#if>
|
||||
<#if 2 == passwordResetResult>
|
||||
|
||||
Reference in New Issue
Block a user