mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-08 09:58:56 +08:00
mobile login
This commit is contained in:
parent
ff3d97d51f
commit
b378f9fa2f
@ -47,12 +47,19 @@ public abstract class AbstractAuthenticationProvider {
|
|||||||
private static final Logger _logger =
|
private static final Logger _logger =
|
||||||
LoggerFactory.getLogger(AbstractAuthenticationProvider.class);
|
LoggerFactory.getLogger(AbstractAuthenticationProvider.class);
|
||||||
|
|
||||||
|
public class AuthType{
|
||||||
|
public final static String NORMAL = "normal";
|
||||||
|
public final static String TFA = "tfa";
|
||||||
|
public final static String MOBILE = "mobile";
|
||||||
|
}
|
||||||
protected ApplicationConfig applicationConfig;
|
protected ApplicationConfig applicationConfig;
|
||||||
|
|
||||||
protected AbstractAuthenticationRealm authenticationRealm;
|
protected AbstractAuthenticationRealm authenticationRealm;
|
||||||
|
|
||||||
protected AbstractOtpAuthn tfaOtpAuthn;
|
protected AbstractOtpAuthn tfaOtpAuthn;
|
||||||
|
|
||||||
|
protected AbstractOtpAuthn smsOtpAuthn;
|
||||||
|
|
||||||
protected AbstractRemeberMeService remeberMeService;
|
protected AbstractRemeberMeService remeberMeService;
|
||||||
|
|
||||||
protected OnlineTicketServices onlineTicketServices;
|
protected OnlineTicketServices onlineTicketServices;
|
||||||
@ -176,8 +183,10 @@ public abstract class AbstractAuthenticationProvider {
|
|||||||
protected void authTypeValid(String authType) {
|
protected void authTypeValid(String authType) {
|
||||||
_logger.debug("Login AuthN Type " + authType);
|
_logger.debug("Login AuthN Type " + authType);
|
||||||
if (authType != null && (
|
if (authType != null && (
|
||||||
authType.equalsIgnoreCase("basic")
|
authType.equalsIgnoreCase(AuthType.NORMAL)
|
||||||
|| authType.equalsIgnoreCase("tfa"))
|
|| authType.equalsIgnoreCase(AuthType.TFA)
|
||||||
|
|| authType.equalsIgnoreCase(AuthType.MOBILE)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -195,7 +204,8 @@ public abstract class AbstractAuthenticationProvider {
|
|||||||
*/
|
*/
|
||||||
protected void captchaValid(String captcha, String authType) {
|
protected void captchaValid(String captcha, String authType) {
|
||||||
// for basic
|
// for basic
|
||||||
if (applicationConfig.getLoginConfig().isCaptcha() && authType.equalsIgnoreCase("basic")) {
|
if (applicationConfig.getLoginConfig().isCaptcha()
|
||||||
|
&& authType.equalsIgnoreCase(AuthType.NORMAL)) {
|
||||||
_logger.info("captcha : "
|
_logger.info("captcha : "
|
||||||
+ WebContext.getSession().getAttribute(
|
+ WebContext.getSession().getAttribute(
|
||||||
WebConstants.KAPTCHA_SESSION_KEY).toString());
|
WebConstants.KAPTCHA_SESSION_KEY).toString());
|
||||||
@ -218,7 +228,8 @@ 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().isMfa() && authType.equalsIgnoreCase("tfa")) {
|
if (applicationConfig.getLoginConfig().isMfa()
|
||||||
|
&& authType.equalsIgnoreCase(AuthType.TFA)) {
|
||||||
UserInfo validUserInfo = new UserInfo();
|
UserInfo validUserInfo = new UserInfo();
|
||||||
validUserInfo.setUsername(userInfo.getUsername());
|
validUserInfo.setUsername(userInfo.getUsername());
|
||||||
validUserInfo.setSharedSecret(userInfo.getSharedSecret());
|
validUserInfo.setSharedSecret(userInfo.getSharedSecret());
|
||||||
@ -232,6 +243,28 @@ public abstract class AbstractAuthenticationProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mobile validate.
|
||||||
|
*
|
||||||
|
* @param otpCaptcha String
|
||||||
|
* @param authType String
|
||||||
|
* @param userInfo UserInfo
|
||||||
|
*/
|
||||||
|
protected void mobilecaptchaValid(String password, String authType, UserInfo userInfo) {
|
||||||
|
// for mobile password
|
||||||
|
if (applicationConfig.getLoginConfig().isMfa()
|
||||||
|
&& authType.equalsIgnoreCase(AuthType.MOBILE)) {
|
||||||
|
UserInfo validUserInfo = new UserInfo();
|
||||||
|
validUserInfo.setUsername(userInfo.getUsername());
|
||||||
|
validUserInfo.setId(userInfo.getId());
|
||||||
|
if (password == null || !smsOtpAuthn.validate(validUserInfo, password)) {
|
||||||
|
String message = WebContext.getI18nValue("login.error.captcha");
|
||||||
|
_logger.debug("login captcha valid error.");
|
||||||
|
throw new BadCredentialsException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* login user by j_username and j_cname first query user by j_cname if first
|
* login user by j_username and j_cname first query user by j_cname if first
|
||||||
* step userinfo is null,query user from system.
|
* step userinfo is null,query user from system.
|
||||||
@ -329,6 +362,7 @@ public abstract class AbstractAuthenticationProvider {
|
|||||||
this.onlineTicketServices = onlineTicketServices;
|
this.onlineTicketServices = onlineTicketServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSmsOtpAuthn(AbstractOtpAuthn smsOtpAuthn) {
|
||||||
|
this.smsOtpAuthn = smsOtpAuthn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,11 +62,13 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
|
|||||||
AbstractAuthenticationRealm authenticationRealm,
|
AbstractAuthenticationRealm authenticationRealm,
|
||||||
ApplicationConfig applicationConfig,
|
ApplicationConfig applicationConfig,
|
||||||
AbstractOtpAuthn tfaOtpAuthn,
|
AbstractOtpAuthn tfaOtpAuthn,
|
||||||
|
AbstractOtpAuthn smsOtpAuthn,
|
||||||
AbstractRemeberMeService remeberMeService,
|
AbstractRemeberMeService remeberMeService,
|
||||||
OnlineTicketServices onlineTicketServices) {
|
OnlineTicketServices onlineTicketServices) {
|
||||||
this.authenticationRealm = authenticationRealm;
|
this.authenticationRealm = authenticationRealm;
|
||||||
this.applicationConfig = applicationConfig;
|
this.applicationConfig = applicationConfig;
|
||||||
this.tfaOtpAuthn = tfaOtpAuthn;
|
this.tfaOtpAuthn = tfaOtpAuthn;
|
||||||
|
this.smsOtpAuthn = smsOtpAuthn;
|
||||||
this.remeberMeService = remeberMeService;
|
this.remeberMeService = remeberMeService;
|
||||||
this.onlineTicketServices = onlineTicketServices;
|
this.onlineTicketServices = onlineTicketServices;
|
||||||
}
|
}
|
||||||
@ -96,9 +98,12 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
|
|||||||
|
|
||||||
tftcaptchaValid(loginCredential.getOtpCaptcha(),loginCredential.getAuthType(),userInfo);
|
tftcaptchaValid(loginCredential.getOtpCaptcha(),loginCredential.getAuthType(),userInfo);
|
||||||
|
|
||||||
|
if(loginCredential.getAuthType().equalsIgnoreCase(AuthType.MOBILE)) {
|
||||||
|
mobilecaptchaValid(loginCredential.getPassword(),loginCredential.getAuthType(),userInfo);
|
||||||
|
}else {
|
||||||
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo);
|
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo);
|
||||||
|
|
||||||
authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword());
|
authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authenticationToken = setOnline(loginCredential,userInfo);
|
UsernamePasswordAuthenticationToken authenticationToken = setOnline(loginCredential,userInfo);
|
||||||
//RemeberMe Config check then set RemeberMe cookies
|
//RemeberMe Config check then set RemeberMe cookies
|
||||||
|
|||||||
@ -51,7 +51,6 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
||||||
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||||
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
||||||
@ -77,14 +76,17 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
|
|||||||
AbstractAuthenticationRealm authenticationRealm,
|
AbstractAuthenticationRealm authenticationRealm,
|
||||||
ApplicationConfig applicationConfig,
|
ApplicationConfig applicationConfig,
|
||||||
AbstractOtpAuthn tfaOtpAuthn,
|
AbstractOtpAuthn tfaOtpAuthn,
|
||||||
|
AbstractOtpAuthn smsOtpAuthn,
|
||||||
AbstractRemeberMeService remeberMeService,
|
AbstractRemeberMeService remeberMeService,
|
||||||
OnlineTicketServices onlineTicketServices
|
OnlineTicketServices onlineTicketServices
|
||||||
) {
|
) {
|
||||||
|
|
||||||
_logger.debug("init authenticationProvider .");
|
_logger.debug("init authenticationProvider .");
|
||||||
return new RealmAuthenticationProvider(
|
return new RealmAuthenticationProvider(
|
||||||
authenticationRealm,
|
authenticationRealm,
|
||||||
applicationConfig,
|
applicationConfig,
|
||||||
tfaOtpAuthn,
|
tfaOtpAuthn,
|
||||||
|
smsOtpAuthn,
|
||||||
remeberMeService,
|
remeberMeService,
|
||||||
onlineTicketServices
|
onlineTicketServices
|
||||||
);
|
);
|
||||||
|
|||||||
@ -47,13 +47,12 @@ public class SmsOtpAuthn extends AbstractOtpAuthn {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProperties(Properties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
protected void loadProperties() throws IOException {
|
protected void loadProperties() throws IOException {
|
||||||
Resource resource = new ClassPathResource(
|
|
||||||
ConstantsProperties.classPathResource(
|
|
||||||
ConstantsProperties.classPathResource(
|
|
||||||
ConstantsProperties.applicationPropertySource)));
|
|
||||||
properties = new Properties();
|
|
||||||
properties.load(resource.getInputStream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initPropertys() {
|
public void initPropertys() {
|
||||||
|
|||||||
@ -138,10 +138,10 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.accessKeyId = this.properties.getProperty("config.otp.sms.aliyun.accesskeyid");
|
this.accessKeyId = this.properties.getProperty("maxkey.otp.sms.aliyun.accesskeyid");
|
||||||
this.accessSecret = this.properties.getProperty("config.otp.sms.aliyun.accesssecret");
|
this.accessSecret = this.properties.getProperty("maxkey.otp.sms.aliyun.accesssecret");
|
||||||
this.templateCode = this.properties.getProperty("config.otp.sms.aliyun.templatecode");
|
this.templateCode = this.properties.getProperty("maxkey.otp.sms.aliyun.templatecode");
|
||||||
this.signName = this.properties.getProperty("config.otp.sms.aliyun.signname");
|
this.signName = this.properties.getProperty("maxkey.otp.sms.aliyun.signname");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -181,11 +181,11 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.secretId = this.properties.getProperty("config.otp.sms.tencentcloud.secretid");
|
this.secretId = this.properties.getProperty("maxkey.otp.sms.tencentcloud.secretid");
|
||||||
this.secretKey = this.properties.getProperty("config.otp.sms.tencentcloud.secretkey");
|
this.secretKey = this.properties.getProperty("maxkey.otp.sms.tencentcloud.secretkey");
|
||||||
this.smsSdkAppid = this.properties.getProperty("config.otp.sms.tencentcloud.smssdkappid");
|
this.smsSdkAppid = this.properties.getProperty("maxkey.otp.sms.tencentcloud.smssdkappid");
|
||||||
this.templateId = this.properties.getProperty("config.otp.sms.tencentcloud.templateid");
|
this.templateId = this.properties.getProperty("maxkey.otp.sms.tencentcloud.templateid");
|
||||||
this.sign = this.properties.getProperty("config.otp.sms.tencentcloud.sign");
|
this.sign = this.properties.getProperty("maxkey.otp.sms.tencentcloud.sign");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,7 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
|||||||
).randomGenerate();
|
).randomGenerate();
|
||||||
String checkSum = SmsOtpAuthnYunxinCheckSumBuilder
|
String checkSum = SmsOtpAuthnYunxinCheckSumBuilder
|
||||||
.getCheckSum(appSecret, nonce, curTime);
|
.getCheckSum(appSecret, nonce, curTime);
|
||||||
|
logger.debug("AppKey " +appKey+" ,Nonce "+nonce+", CurTime "+curTime+" ,checkSum "+checkSum);
|
||||||
// 设置请求的header
|
// 设置请求的header
|
||||||
httpPost.addHeader("AppKey", appKey);
|
httpPost.addHeader("AppKey", appKey);
|
||||||
httpPost.addHeader("Nonce", nonce);
|
httpPost.addHeader("Nonce", nonce);
|
||||||
@ -118,9 +118,11 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
|||||||
YunxinSms yunxinSms =
|
YunxinSms yunxinSms =
|
||||||
JsonUtils.gson2Object(responseString,YunxinSms.class);
|
JsonUtils.gson2Object(responseString,YunxinSms.class);
|
||||||
logger.debug("responseEntity code " + yunxinSms.getObj());
|
logger.debug("responseEntity code " + yunxinSms.getObj());
|
||||||
|
nonce = yunxinSms.getObj() == null ?nonce:yunxinSms.getObj();
|
||||||
|
logger.debug("nonce " + nonce);
|
||||||
this.optTokenStore.store(
|
this.optTokenStore.store(
|
||||||
userInfo,
|
userInfo,
|
||||||
yunxinSms.getObj(),
|
nonce,
|
||||||
userInfo.getMobile(),
|
userInfo.getMobile(),
|
||||||
OtpTypes.SMS);
|
OtpTypes.SMS);
|
||||||
return true;
|
return true;
|
||||||
@ -210,9 +212,9 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.appKey = this.properties.getProperty("config.otp.sms.yunxin.appkey");
|
this.appKey = this.properties.getProperty("maxkey.otp.sms.yunxin.appkey");
|
||||||
this.appSecret = this.properties.getProperty("config.otp.sms.yunxin.appsecret");
|
this.appSecret = this.properties.getProperty("maxkey.otp.sms.yunxin.appsecret");
|
||||||
this.templateId = this.properties.getProperty("config.otp.sms.yunxin.templateid");
|
this.templateId = this.properties.getProperty("maxkey.otp.sms.yunxin.templateid");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -35,14 +35,14 @@ public class SmsOtpAuthnYunxinCheckSumBuilder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
|
MessageDigest messageDigest
|
||||||
|
= MessageDigest.getInstance(algorithm);
|
||||||
messageDigest.update(value.getBytes());
|
messageDigest.update(value.getBytes());
|
||||||
return getFormattedText(messageDigest.digest());
|
return getFormattedText(messageDigest.digest());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getFormattedText(byte[] bytes) {
|
private static String getFormattedText(byte[] bytes) {
|
||||||
int len = bytes.length;
|
int len = bytes.length;
|
||||||
StringBuilder buf = new StringBuilder(len * 2);
|
StringBuilder buf = new StringBuilder(len * 2);
|
||||||
@ -52,8 +52,6 @@ public class SmsOtpAuthnYunxinCheckSumBuilder {
|
|||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
|
||||||
private static final char[] HEX_DIGITS = {
|
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
|
||||||
'a', 'b', 'c', 'd','e', 'f' };
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.maxkey.authn.support.socialsignon.service.JdbcSocialsAssociateService;
|
import org.maxkey.authn.support.socialsignon.service.JdbcSocialsAssociateService;
|
||||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
|
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
|
||||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
|
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
|
||||||
@ -29,14 +28,11 @@ import org.maxkey.constants.ConstantsProperties;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
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.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -50,27 +46,17 @@ public class SocialSignOnAutoConfiguration implements InitializingBean {
|
|||||||
@Bean(name = "socialSignOnProviderService")
|
@Bean(name = "socialSignOnProviderService")
|
||||||
@ConditionalOnClass(SocialSignOnProvider.class)
|
@ConditionalOnClass(SocialSignOnProvider.class)
|
||||||
public SocialSignOnProviderService socialSignOnProviderService(
|
public SocialSignOnProviderService socialSignOnProviderService(
|
||||||
@Value("${spring.profiles.active}")String profilesActive) throws IOException {
|
Properties applicationProperty) throws IOException {
|
||||||
SocialSignOnProviderService socialSignOnProviderService = new SocialSignOnProviderService();
|
SocialSignOnProviderService socialSignOnProviderService = new SocialSignOnProviderService();
|
||||||
|
|
||||||
_logger.trace("spring.profiles.active " + profilesActive);
|
String [] providerList =applicationProperty.get("maxkey.login.socialsignon.providers").toString().split(",");
|
||||||
|
|
||||||
Resource resource = new ClassPathResource(
|
|
||||||
ConstantsProperties.classPathResource(
|
|
||||||
ConstantsProperties.classPathResource(
|
|
||||||
ConstantsProperties.applicationPropertySource,
|
|
||||||
profilesActive)));
|
|
||||||
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.load(resource.getInputStream());
|
|
||||||
String [] providerList =properties.get("maxkey.login.socialsignon.providers").toString().split(",");
|
|
||||||
List<SocialSignOnProvider> socialSignOnProviderList = new ArrayList<SocialSignOnProvider>();
|
List<SocialSignOnProvider> socialSignOnProviderList = new ArrayList<SocialSignOnProvider>();
|
||||||
for(String provider : providerList) {
|
for(String provider : providerList) {
|
||||||
String providerName = properties.getProperty("maxkey.socialsignon."+provider+".provider.name");
|
String providerName = applicationProperty.getProperty("maxkey.socialsignon."+provider+".provider.name");
|
||||||
String icon=properties.getProperty("maxkey.socialsignon."+provider+".icon");
|
String icon=applicationProperty.getProperty("maxkey.socialsignon."+provider+".icon");
|
||||||
String clientId=properties.getProperty("maxkey.socialsignon."+provider+".client.id");
|
String clientId=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.id");
|
||||||
String clientSecret=properties.getProperty("maxkey.socialsignon."+provider+".client.secret");
|
String clientSecret=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.secret");
|
||||||
String sortOrder = properties.getProperty("maxkey.socialsignon."+provider+".sortorder");
|
String sortOrder = applicationProperty.getProperty("maxkey.socialsignon."+provider+".sortorder");
|
||||||
SocialSignOnProvider socialSignOnProvider = new SocialSignOnProvider();
|
SocialSignOnProvider socialSignOnProvider = new SocialSignOnProvider();
|
||||||
socialSignOnProvider.setProvider(provider);
|
socialSignOnProvider.setProvider(provider);
|
||||||
socialSignOnProvider.setProviderName(providerName);
|
socialSignOnProvider.setProviderName(providerName);
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import org.maxkey.constants.ConstantsProperties;
|
import org.maxkey.constants.ConstantsProperties;
|
||||||
@ -82,19 +83,30 @@ public class ApplicationAutoConfiguration implements InitializingBean {
|
|||||||
new ClassPathResource(ConstantsProperties.classPathResource(
|
new ClassPathResource(ConstantsProperties.classPathResource(
|
||||||
ConstantsProperties.applicationPropertySource));
|
ConstantsProperties.applicationPropertySource));
|
||||||
|
|
||||||
|
|
||||||
PropertySourcesPlaceholderConfigurer configurer =
|
PropertySourcesPlaceholderConfigurer configurer =
|
||||||
new PropertySourcesPlaceholderConfigurer();
|
new PropertySourcesPlaceholderConfigurer();
|
||||||
configurer.setLocations(classPathApplicationPropertySource);
|
configurer.setLocations(classPathApplicationPropertySource);
|
||||||
/*configurer.setLocations(
|
|
||||||
classPathResource1,
|
|
||||||
classPathResource2
|
|
||||||
);*/
|
|
||||||
configurer.setIgnoreUnresolvablePlaceholders(true);
|
configurer.setIgnoreUnresolvablePlaceholders(true);
|
||||||
_logger.debug("PropertySourcesPlaceholderConfigurer init");
|
_logger.debug("PropertySourcesPlaceholderConfigurer init");
|
||||||
|
|
||||||
return configurer;
|
return configurer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean (name = "applicationProperty")
|
||||||
|
public Properties applicationProperty(
|
||||||
|
@Value("${spring.profiles.active:}")String profilesActive) throws IOException {
|
||||||
|
Resource resource = new ClassPathResource(
|
||||||
|
ConstantsProperties.classPathResource(
|
||||||
|
ConstantsProperties.classPathResource(
|
||||||
|
ConstantsProperties.applicationPropertySource,
|
||||||
|
profilesActive)));
|
||||||
|
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(resource.getInputStream());
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean(name = "passwordReciprocal")
|
@Bean(name = "passwordReciprocal")
|
||||||
public PasswordReciprocal passwordReciprocal() {
|
public PasswordReciprocal passwordReciprocal() {
|
||||||
return new PasswordReciprocal();
|
return new PasswordReciprocal();
|
||||||
|
|||||||
@ -67,7 +67,7 @@ public class LoginService {
|
|||||||
/**
|
/**
|
||||||
* 1 (USERNAME) 2 (USERNAME | MOBILE) 3 (USERNAME | MOBILE | EMAIL)
|
* 1 (USERNAME) 2 (USERNAME | MOBILE) 3 (USERNAME | MOBILE | EMAIL)
|
||||||
*/
|
*/
|
||||||
public static int LOGIN_ATTRIBUTE_TYPE = 1;
|
public static int LOGIN_ATTRIBUTE_TYPE = 2;
|
||||||
|
|
||||||
public LoginService(){
|
public LoginService(){
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
<div class="form-group text-center m-t-20">
|
<div class="form-group text-center m-t-20">
|
||||||
<input type="hidden" name="authType" value="basic" />
|
<input type="hidden" name="authType" value="normal" />
|
||||||
<input type='hidden' id="sessionid" name="sessionId" value="${sessionid}" />
|
<input type='hidden' id="sessionid" name="sessionId" value="${sessionid}" />
|
||||||
<button id="loginSubmit" class="button btn-primary btn btn-common btn-block" type="submit">
|
<button id="loginSubmit" class="button btn-primary btn btn-common btn-block" type="submit">
|
||||||
<@locale code="login.button.login" />
|
<@locale code="login.button.login" />
|
||||||
|
|||||||
@ -19,6 +19,8 @@ package org.maxkey;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm;
|
import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm;
|
||||||
import org.maxkey.authn.realm.ldap.LdapAuthenticationRealm;
|
import org.maxkey.authn.realm.ldap.LdapAuthenticationRealm;
|
||||||
import org.maxkey.authn.realm.ldap.LdapServer;
|
import org.maxkey.authn.realm.ldap.LdapServer;
|
||||||
@ -164,7 +166,13 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
@Value("${maxkey.support.ldap.basedn}")String baseDN,
|
@Value("${maxkey.support.ldap.basedn}")String baseDN,
|
||||||
@Value("${maxkey.support.ldap.domain}")String domain,
|
@Value("${maxkey.support.ldap.domain}")String domain,
|
||||||
@Value("${maxkey.support.ldap.product:openldap}")String product) {
|
@Value("${maxkey.support.ldap.product:openldap}")String product) {
|
||||||
|
AbstractAuthenticationRealm ldapAuthenticationRealm =
|
||||||
|
ldapAuthenticationRealm(
|
||||||
|
ldapSupport,ldapJit,
|
||||||
|
providerUrl,principal,credentials,
|
||||||
|
filter,baseDN,domain,product,
|
||||||
|
jdbcTemplate
|
||||||
|
);
|
||||||
JdbcAuthenticationRealm authenticationRealm = new JdbcAuthenticationRealm(
|
JdbcAuthenticationRealm authenticationRealm = new JdbcAuthenticationRealm(
|
||||||
passwordEncoder,
|
passwordEncoder,
|
||||||
passwordPolicyValidator,
|
passwordPolicyValidator,
|
||||||
@ -172,18 +180,13 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
loginHistoryService,
|
loginHistoryService,
|
||||||
remeberMeService,
|
remeberMeService,
|
||||||
jdbcTemplate,
|
jdbcTemplate,
|
||||||
ldapAuthenticationRealm(
|
ldapAuthenticationRealm,
|
||||||
ldapSupport,ldapJit,
|
ldapSupport
|
||||||
providerUrl,principal,credentials,
|
);
|
||||||
filter,baseDN,domain,product,
|
|
||||||
jdbcTemplate),
|
|
||||||
ldapSupport);
|
|
||||||
|
|
||||||
return authenticationRealm;
|
return authenticationRealm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Bean(name = "timeBasedOtpAuthn")
|
@Bean(name = "timeBasedOtpAuthn")
|
||||||
public TimeBasedOtpAuthn timeBasedOtpAuthn() {
|
public TimeBasedOtpAuthn timeBasedOtpAuthn() {
|
||||||
TimeBasedOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn();
|
TimeBasedOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn();
|
||||||
@ -191,31 +194,13 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
return tfaOtpAuthn;
|
return tfaOtpAuthn;
|
||||||
}
|
}
|
||||||
|
|
||||||
//default tfaOtpAuthn
|
|
||||||
@Bean(name = "tfaOtpAuthn")
|
@Bean(name = "tfaOtpAuthn")
|
||||||
public AbstractOtpAuthn tfaOptAuthn(
|
public AbstractOtpAuthn tfaOptAuthn(
|
||||||
@Value("${maxkey.login.mfa.type}")String mfaType,
|
@Value("${maxkey.login.mfa.type}")String mfaType,
|
||||||
@Value("${maxkey.server.persistence}") int persistence,
|
@Value("${maxkey.server.persistence}") int persistence,
|
||||||
MailOtpAuthn tfaMailOtpAuthn,
|
|
||||||
RedisConnectionFactory redisConnFactory) {
|
RedisConnectionFactory redisConnFactory) {
|
||||||
|
AbstractOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn();
|
||||||
AbstractOtpAuthn tfaOtpAuthn = null;
|
|
||||||
if(mfaType.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
|
|
||||||
tfaOtpAuthn = new SmsOtpAuthnAliyun();
|
|
||||||
_logger.debug("SmsOtpAuthnAliyun inited.");
|
|
||||||
}else if(mfaType.equalsIgnoreCase("SmsOtpAuthnTencentCloud")) {
|
|
||||||
tfaOtpAuthn = new SmsOtpAuthnTencentCloud();
|
|
||||||
_logger.debug("SmsOtpAuthnTencentCloud inited.");
|
|
||||||
}else if(mfaType.equalsIgnoreCase("SmsOtpAuthnYunxin")) {
|
|
||||||
tfaOtpAuthn = new SmsOtpAuthnYunxin();
|
|
||||||
_logger.debug("SmsOtpAuthnYunxin inited.");
|
|
||||||
}else if(mfaType.equalsIgnoreCase("MailOtpAuthn")) {
|
|
||||||
tfaOtpAuthn = tfaMailOtpAuthn;
|
|
||||||
_logger.debug("MailOtpAuthn inited.");
|
|
||||||
}else {
|
|
||||||
tfaOtpAuthn = new TimeBasedOtpAuthn();
|
|
||||||
_logger.debug("TimeBasedOtpAuthn inited.");
|
_logger.debug("TimeBasedOtpAuthn inited.");
|
||||||
}
|
|
||||||
|
|
||||||
if (persistence == ConstantsPersistence.REDIS) {
|
if (persistence == ConstantsPersistence.REDIS) {
|
||||||
RedisOtpTokenStore redisOptTokenStore = new RedisOtpTokenStore(redisConnFactory);
|
RedisOtpTokenStore redisOptTokenStore = new RedisOtpTokenStore(redisConnFactory);
|
||||||
@ -226,7 +211,7 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
return tfaOtpAuthn;
|
return tfaOtpAuthn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "tfaMailOtpAuthn")
|
@Bean(name = "mailOtpAuthn")
|
||||||
public MailOtpAuthn mailOtpAuthn(
|
public MailOtpAuthn mailOtpAuthn(
|
||||||
@Value("${spring.mail.properties.mailotp.message.subject}")
|
@Value("${spring.mail.properties.mailotp.message.subject}")
|
||||||
String messageSubject,
|
String messageSubject,
|
||||||
@ -236,14 +221,15 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn();
|
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn();
|
||||||
mailOtpAuthn.setSubject(messageSubject);
|
mailOtpAuthn.setSubject(messageSubject);
|
||||||
mailOtpAuthn.setMessageTemplate(messageTemplate);
|
mailOtpAuthn.setMessageTemplate(messageTemplate);
|
||||||
_logger.debug("tfaMailOtpAuthn inited.");
|
_logger.debug("MailOtpAuthn inited.");
|
||||||
return mailOtpAuthn;
|
return mailOtpAuthn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "tfaMobileOtpAuthn")
|
@Bean(name = "smsOtpAuthn")
|
||||||
public SmsOtpAuthn smsOtpAuthn(
|
public SmsOtpAuthn smsOtpAuthn(
|
||||||
@Value("${maxkey.otp.sms}")String optSmsProvider,
|
@Value("${maxkey.otp.sms}")String optSmsProvider,
|
||||||
@Value("${maxkey.server.persistence}") int persistence,
|
@Value("${maxkey.server.persistence}") int persistence,
|
||||||
|
Properties applicationProperty,
|
||||||
RedisConnectionFactory redisConnFactory) {
|
RedisConnectionFactory redisConnFactory) {
|
||||||
SmsOtpAuthn smsOtpAuthn = null;
|
SmsOtpAuthn smsOtpAuthn = null;
|
||||||
if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
|
if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
|
||||||
@ -257,6 +243,7 @@ public class MaxKeyConfig implements InitializingBean {
|
|||||||
RedisOtpTokenStore redisOptTokenStore = new RedisOtpTokenStore(redisConnFactory);
|
RedisOtpTokenStore redisOptTokenStore = new RedisOtpTokenStore(redisConnFactory);
|
||||||
smsOtpAuthn.setOptTokenStore(redisOptTokenStore);
|
smsOtpAuthn.setOptTokenStore(redisOptTokenStore);
|
||||||
}
|
}
|
||||||
|
smsOtpAuthn.setProperties(applicationProperty);
|
||||||
smsOtpAuthn.initPropertys();
|
smsOtpAuthn.initPropertys();
|
||||||
|
|
||||||
_logger.debug("SmsOtpAuthn inited.");
|
_logger.debug("SmsOtpAuthn inited.");
|
||||||
|
|||||||
@ -62,12 +62,12 @@ public class ForgotPasswordContorller {
|
|||||||
private UserInfoService userInfoService;
|
private UserInfoService userInfoService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("tfaMailOtpAuthn")
|
@Qualifier("mailOtpAuthn")
|
||||||
protected AbstractOtpAuthn tfaMailOtpAuthn;
|
protected AbstractOtpAuthn mailOtpAuthn;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("tfaMobileOtpAuthn")
|
@Qualifier("smsOtpAuthn")
|
||||||
protected AbstractOtpAuthn tfaMobileOtpAuthn;
|
protected AbstractOtpAuthn smsOtpAuthn;
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = { "/forward" })
|
@RequestMapping(value = { "/forward" })
|
||||||
@ -89,10 +89,10 @@ public class ForgotPasswordContorller {
|
|||||||
|
|
||||||
Matcher matcher = emailRegex.matcher(emailMobile);
|
Matcher matcher = emailRegex.matcher(emailMobile);
|
||||||
if (matcher.matches() && null != userInfo) {
|
if (matcher.matches() && null != userInfo) {
|
||||||
tfaMailOtpAuthn.produce(userInfo);
|
mailOtpAuthn.produce(userInfo);
|
||||||
forgotType = ForgotType.EMAIL;
|
forgotType = ForgotType.EMAIL;
|
||||||
}else if (null != userInfo) {
|
}else if (null != userInfo) {
|
||||||
tfaMobileOtpAuthn.produce(userInfo);
|
smsOtpAuthn.produce(userInfo);
|
||||||
forgotType = ForgotType.MOBILE;
|
forgotType = ForgotType.MOBILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +126,8 @@ public class ForgotPasswordContorller {
|
|||||||
userInfo.setUsername(username);
|
userInfo.setUsername(username);
|
||||||
userInfo.setPassword(password);
|
userInfo.setPassword(password);
|
||||||
userInfo.setDecipherable(password);
|
userInfo.setDecipherable(password);
|
||||||
if ((forgotType == ForgotType.EMAIL && tfaMailOtpAuthn.validate(userInfo, captcha)) ||
|
if ((forgotType == ForgotType.EMAIL && mailOtpAuthn.validate(userInfo, captcha)) ||
|
||||||
(forgotType == ForgotType.MOBILE && tfaMobileOtpAuthn.validate(userInfo, captcha))
|
(forgotType == ForgotType.MOBILE && smsOtpAuthn.validate(userInfo, captcha))
|
||||||
) {
|
) {
|
||||||
userInfoService.changePassword(userInfo);
|
userInfoService.changePassword(userInfo);
|
||||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
|
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
|
||||||
|
|||||||
@ -19,6 +19,8 @@ package org.maxkey.web.endpoint;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -79,6 +81,13 @@ public class LoginEndpoint {
|
|||||||
@Qualifier("tfaOtpAuthn")
|
@Qualifier("tfaOtpAuthn")
|
||||||
protected AbstractOtpAuthn tfaOtpAuthn;
|
protected AbstractOtpAuthn tfaOtpAuthn;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("smsOtpAuthn")
|
||||||
|
protected AbstractOtpAuthn smsOtpAuthn;
|
||||||
|
|
||||||
|
Pattern mobileRegex = Pattern.compile(
|
||||||
|
"^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\\\d{8}$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init login
|
* init login
|
||||||
* @return
|
* @return
|
||||||
@ -154,14 +163,12 @@ public class LoginEndpoint {
|
|||||||
return authnType;
|
return authnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/login/otp/{username}")
|
@RequestMapping("/login/sendsms/{mobile}")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String produceOtp(@PathVariable("username") String username) {
|
public String produceOtp(@PathVariable("mobile") String mobile) {
|
||||||
UserInfo userInfo = new UserInfo();
|
UserInfo queryUserInfo=userInfoService.queryUserInfoByEmailMobile(mobile);
|
||||||
userInfo.setUsername(username);
|
|
||||||
UserInfo queryUserInfo=userInfoService.loadByUsername(username);//(userInfo);
|
|
||||||
if(queryUserInfo!=null) {
|
if(queryUserInfo!=null) {
|
||||||
tfaOtpAuthn.produce(queryUserInfo);
|
smsOtpAuthn.produce(queryUserInfo);
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -206,9 +206,9 @@ maxkey.otp.sms.aliyun.accesssecret=05d5485357bc
|
|||||||
maxkey.otp.sms.aliyun.templatecode=14860095
|
maxkey.otp.sms.aliyun.templatecode=14860095
|
||||||
maxkey.otp.sms.aliyun.signname=maxkey
|
maxkey.otp.sms.aliyun.signname=maxkey
|
||||||
#yunxin
|
#yunxin
|
||||||
maxkey.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef4
|
maxkey.otp.sms.yunxin.appkey=94395d754eb55693043f5d6a2b772ef3
|
||||||
maxkey.otp.sms.yunxin.appsecret=05d5485357bc
|
maxkey.otp.sms.yunxin.appsecret=05d5485357bc
|
||||||
maxkey.otp.sms.yunxin.templateid=14860095
|
maxkey.otp.sms.yunxin.templateid=14860099
|
||||||
#tencentcloud
|
#tencentcloud
|
||||||
maxkey.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
|
maxkey.otp.sms.tencentcloud.secretid=94395d754eb55693043f5d6a2b772ef4
|
||||||
maxkey.otp.sms.tencentcloud.secretkey=05d5485357bc
|
maxkey.otp.sms.tencentcloud.secretkey=05d5485357bc
|
||||||
|
|||||||
@ -42,11 +42,22 @@ login.text.login.twofactor.obtain=\u83b7\u53d6\u52a8\u6001\u9a8c\u8bc1\u7801
|
|||||||
login.text.login.twofactor.obtain.valid.unit=\u79d2
|
login.text.login.twofactor.obtain.valid.unit=\u79d2
|
||||||
login.text.login.twofactor.validTime=\u5269\u4f59\u65f6\u95f4
|
login.text.login.twofactor.validTime=\u5269\u4f59\u65f6\u95f4
|
||||||
login.text.login.twofactor.validTime.unit=\u79d2
|
login.text.login.twofactor.validTime.unit=\u79d2
|
||||||
|
|
||||||
|
login.text.login.mobile.obtain.valid=\u91cd\u65b0\u83b7\u53d6
|
||||||
|
login.text.login.mobile.obtain=\u53D1\u9001\u9a8c\u8bc1\u7801
|
||||||
|
login.text.login.mobile.obtain.valid.unit=\u79d2
|
||||||
|
login.text.login.mobile.validTime=\u5269\u4f59\u65f6\u95f4
|
||||||
|
login.text.login.mobile.validTime.unit=\u79d2
|
||||||
|
|
||||||
login.text.login.twofactor=\u5b89\u5168\u8ba4\u8bc1
|
login.text.login.twofactor=\u5b89\u5168\u8ba4\u8bc1
|
||||||
login.text.login.normal=\u57fa\u672c\u8ba4\u8bc1
|
login.text.login.normal=\u57fa\u672c\u8ba4\u8bc1
|
||||||
|
login.text.login.mobile=\u624B\u673A\u767B\u5F55
|
||||||
|
|
||||||
login.text.username=\u7528\u6237\u540d
|
login.text.username=\u7528\u6237\u540d
|
||||||
|
login.text.mobile=\u624B\u673A\u53F7\u7801
|
||||||
login.text.password=\u5bc6 \u7801
|
login.text.password=\u5bc6 \u7801
|
||||||
login.text.captcha=\u9a8c\u8bc1\u7801
|
login.text.captcha=\u9a8c\u8bc1\u7801
|
||||||
|
login.text.smscode=\u77ED\u4FE1\u9a8c\u8bc1\u7801
|
||||||
login.text.remeberme=\u8bb0\u4f4f\u767b\u5f55
|
login.text.remeberme=\u8bb0\u4f4f\u767b\u5f55
|
||||||
login.text.forgotpassword=\u5fd8\u8bb0\u5bc6\u7801
|
login.text.forgotpassword=\u5fd8\u8bb0\u5bc6\u7801
|
||||||
login.button.login=\u767b\u5f55
|
login.button.login=\u767b\u5f55
|
||||||
|
|||||||
@ -42,11 +42,22 @@ login.text.login.twofactor.obtain=Get dynamic verification code
|
|||||||
login.text.login.twofactor.obtain.valid.unit=seconds
|
login.text.login.twofactor.obtain.valid.unit=seconds
|
||||||
login.text.login.twofactor.validTime=Remaining
|
login.text.login.twofactor.validTime=Remaining
|
||||||
login.text.login.twofactor.validTime.unit=seconds
|
login.text.login.twofactor.validTime.unit=seconds
|
||||||
|
|
||||||
|
login.text.login.mobile.obtain.valid=Resend
|
||||||
|
login.text.login.mobile.obtain=Send code
|
||||||
|
login.text.login.mobile.obtain.valid.unit=seconds
|
||||||
|
login.text.login.mobile.validTime=Remaining
|
||||||
|
login.text.login.mobile.validTime.unit=seconds
|
||||||
|
|
||||||
login.text.login.twofactor=Two-Factors
|
login.text.login.twofactor=Two-Factors
|
||||||
login.text.login.normal=Normal Login
|
login.text.login.normal=Normal Login
|
||||||
|
login.text.login.mobile=Mobile Login
|
||||||
|
|
||||||
login.text.username=Username
|
login.text.username=Username
|
||||||
|
login.text.mobile=Phone Number
|
||||||
login.text.password=Password
|
login.text.password=Password
|
||||||
login.text.captcha=CAPTCHA
|
login.text.captcha=CAPTCHA
|
||||||
|
login.text.smscode=Message Code
|
||||||
login.text.remeberme=RemeberMe
|
login.text.remeberme=RemeberMe
|
||||||
login.text.forgotpassword=Forgot Password
|
login.text.forgotpassword=Forgot Password
|
||||||
login.button.login=Login
|
login.button.login=Login
|
||||||
|
|||||||
@ -42,11 +42,22 @@ login.text.login.twofactor.obtain=\u83b7\u53d6\u52a8\u6001\u9a8c\u8bc1\u7801
|
|||||||
login.text.login.twofactor.obtain.valid.unit=\u79d2
|
login.text.login.twofactor.obtain.valid.unit=\u79d2
|
||||||
login.text.login.twofactor.validTime=\u5269\u4f59\u65f6\u95f4
|
login.text.login.twofactor.validTime=\u5269\u4f59\u65f6\u95f4
|
||||||
login.text.login.twofactor.validTime.unit=\u79d2
|
login.text.login.twofactor.validTime.unit=\u79d2
|
||||||
|
|
||||||
|
login.text.login.mobile.obtain.valid=\u91cd\u65b0\u83b7\u53d6
|
||||||
|
login.text.login.mobile.obtain=\u53D1\u9001\u9a8c\u8bc1\u7801
|
||||||
|
login.text.login.mobile.obtain.valid.unit=\u79d2
|
||||||
|
login.text.login.mobile.validTime=\u5269\u4f59\u65f6\u95f4
|
||||||
|
login.text.login.mobile.validTime.unit=\u79d2
|
||||||
|
|
||||||
login.text.login.twofactor=\u5b89\u5168\u8ba4\u8bc1
|
login.text.login.twofactor=\u5b89\u5168\u8ba4\u8bc1
|
||||||
login.text.login.normal=\u57fa\u672c\u8ba4\u8bc1
|
login.text.login.normal=\u57fa\u672c\u8ba4\u8bc1
|
||||||
|
login.text.login.mobile=\u624B\u673A\u767B\u5F55
|
||||||
|
|
||||||
login.text.username=\u7528\u6237\u540d
|
login.text.username=\u7528\u6237\u540d
|
||||||
|
login.text.mobile=\u624B\u673A\u53F7\u7801
|
||||||
login.text.password=\u5bc6 \u7801
|
login.text.password=\u5bc6 \u7801
|
||||||
login.text.captcha=\u9a8c\u8bc1\u7801
|
login.text.captcha=\u9a8c\u8bc1\u7801
|
||||||
|
login.text.smscode=\u77ED\u4FE1\u9a8c\u8bc1\u7801
|
||||||
login.text.remeberme=\u8bb0\u4f4f\u767b\u5f55
|
login.text.remeberme=\u8bb0\u4f4f\u767b\u5f55
|
||||||
login.text.forgotpassword=\u5fd8\u8bb0\u5bc6\u7801
|
login.text.forgotpassword=\u5fd8\u8bb0\u5bc6\u7801
|
||||||
login.button.login=\u767b\u5f55
|
login.button.login=\u767b\u5f55
|
||||||
|
|||||||
@ -310,15 +310,14 @@ body{
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tfa_j_otp_captcha{
|
#tfa_j_otp_captcha,#mobile_j_password{
|
||||||
width :120px;
|
width :110px;
|
||||||
/*width :230px;*/
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tfa_j_otp_captcha_button{
|
#tfa_j_otp_captcha_button,#mobile_j_otp_captcha_button{
|
||||||
width :130px;
|
width :120px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -330,11 +329,11 @@ body{
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
#switch_commonLogin,#switch_tfaLogin{
|
#normalLogin,#tfaLogin,#mobileLogin{
|
||||||
width :49%;
|
width :49%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#div_tfaLogin{
|
#div_tfaLogin , #div_mobileLogin{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,12 +39,12 @@ $(function(){
|
|||||||
$(".switch_tab .switch_tab_class").removeClass("switch_tab_current");
|
$(".switch_tab .switch_tab_class").removeClass("switch_tab_current");
|
||||||
$(this).addClass("switch_tab_current");
|
$(this).addClass("switch_tab_current");
|
||||||
$(".switch_tab li").each(function(){
|
$(".switch_tab li").each(function(){
|
||||||
$("#"+$(this).attr("value")).hide();
|
$("#div_"+$(this).attr("id")).hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#"+$(this).attr("value")).show();
|
$("#div_"+$(this).attr("id")).show();
|
||||||
if (typeof(switchTab) == "function"){
|
if (typeof(switchTab) == "function"){
|
||||||
switchTab($(this).attr("value"));//user define after switch Tab
|
switchTab($(this).attr("id"));//user define after switch Tab
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//document forward
|
//document forward
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -31,12 +31,12 @@
|
|||||||
var captchaCountTimer;
|
var captchaCountTimer;
|
||||||
var captchaCount=60;
|
var captchaCount=60;
|
||||||
function getCaptchaCount(){
|
function getCaptchaCount(){
|
||||||
$("#tfa_j_otp_captcha_button").val("<@locale code="login.text.login.twofactor.obtain.valid"/>("+captchaCount+")<@locale code="login.text.login.twofactor.obtain.valid.unit"/>");
|
$("#mobile_j_otp_captcha_button").val("<@locale code="login.text.login.mobile.obtain.valid"/>("+captchaCount+")<@locale code="login.text.login.mobile.obtain.valid.unit"/>");
|
||||||
|
|
||||||
|
|
||||||
captchaCount--;
|
captchaCount--;
|
||||||
if(captchaCount==0){
|
if(captchaCount==0){
|
||||||
$("#tfa_j_otp_captcha_button").val("<@locale code="login.text.login.twofactor.obtain"/>");
|
$("#mobile_j_otp_captcha_button").val("<@locale code="login.text.login.mobile.obtain"/>");
|
||||||
captchaCount=60;
|
captchaCount=60;
|
||||||
clearInterval(captchaCountTimer);
|
clearInterval(captchaCountTimer);
|
||||||
}
|
}
|
||||||
@ -93,26 +93,20 @@
|
|||||||
$("#tfa_j_otp_captcha_button").val("<@locale code="login.text.login.twofactor.validTime"/>("+timeBaseCount+")<@locale code="login.text.login.twofactor.validTime.unit"/>");
|
$("#tfa_j_otp_captcha_button").val("<@locale code="login.text.login.twofactor.validTime"/>("+timeBaseCount+")<@locale code="login.text.login.twofactor.validTime.unit"/>");
|
||||||
};
|
};
|
||||||
</#if>
|
</#if>
|
||||||
var currentSwitchTab="div_commonLogin";
|
var currentSwitchTab="normalLogin";
|
||||||
<#--submit form-->
|
<#--submit form-->
|
||||||
function doLoginSubmit(){
|
function doLoginSubmit(){
|
||||||
if(currentSwitchTab=="div_commonLogin"){
|
$.cookie("username", $("#"+currentSwitchTab+"Form input[name=username]").val(), { expires: 7 });
|
||||||
$.cookie("username", $("#loginForm input[name=j_username]").val(), { expires: 7 });
|
$("#"+currentSwitchTab+"SubmitButton").click();
|
||||||
$.cookie("switch_form", 1, { expires: 7 });
|
$.cookie("switch_tab", currentSwitchTab, { expires: 7 });
|
||||||
$("#loginSubmitButton").click();
|
|
||||||
}else{
|
|
||||||
$.cookie("username", $("#tfaLoginForm input[name=j_username]").val(), { expires: 7 });
|
|
||||||
$.cookie("switch_form", 2, { expires: 7 });
|
|
||||||
$("#tfaLoginSubmitButton").click();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
<#--switch LoginForm && tfaLoginForm-->
|
<#--switch Login Form-->
|
||||||
function switchTab(id){
|
function switchTab(id){
|
||||||
if($("#"+id+" input[name=j_username]").val()==""){
|
if($("#"+id+"Form input[name=username]").val()==""){
|
||||||
$("#"+id+" input[name=j_username]").focus();
|
$("#"+id+"Form input[name=username]").focus();
|
||||||
}else{
|
}else{
|
||||||
$("#"+id+" input[name=j_password]").focus();
|
$("#"+id+"Form input[name=password]").focus();
|
||||||
}
|
}
|
||||||
currentSwitchTab=id;
|
currentSwitchTab=id;
|
||||||
}
|
}
|
||||||
@ -130,39 +124,30 @@
|
|||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#--submit loginForme-->
|
<#--submit loginForme-->
|
||||||
$("#loginSubmit").on("click",function(){
|
$(".doLoginSubmit").on("click",function(){
|
||||||
doLoginSubmit();
|
|
||||||
});
|
|
||||||
<#--submit tfaLoginForme-->
|
|
||||||
$("#tfa_loginSubmit").on("click",function(){
|
|
||||||
doLoginSubmit();
|
doLoginSubmit();
|
||||||
});
|
});
|
||||||
|
|
||||||
<#--read username cookie for login e-->
|
<#--read username cookie for login e-->
|
||||||
if($.cookie("username")!=undefined&&$.cookie("username")!=""){
|
if($.cookie("username")!=undefined&&$.cookie("username")!=""){
|
||||||
$("input[name=j_username]").val($.cookie("username")==undefined?"":$.cookie("username"));
|
var switch_tab=$.cookie("switch_tab")==undefined?"normalLogin":$.cookie("switch_tab");
|
||||||
$("input[name=j_password]").val("");
|
$("#"+switch_tab).click();
|
||||||
var switch_tab=$.cookie("switch_tab")==undefined?1:$.cookie("switch_tab");
|
$("#"+switch_tab+"Form input[name=username]").val($.cookie("username")==undefined?"":$.cookie("username"));
|
||||||
if(switch_tab==2){
|
$("#div_"+switch_tab+" input[name=password]").focus();
|
||||||
switchTab("switch_tfaLogin");
|
|
||||||
}else{
|
}else{
|
||||||
$("#div_commonLogin input[name=j_password]").focus();
|
$("#div_normalLogin input[name=username]").focus();
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
$("#div_commonLogin input[name=j_username]").focus();
|
|
||||||
}
|
}
|
||||||
<#--resend captchae-->
|
<#--resend captchae-->
|
||||||
$("#tfa_j_otp_captcha_button").on("click",function(){
|
$("#mobile_j_otp_captcha_button").on("click",function(){
|
||||||
if(captchaCount<60){
|
if(captchaCount<60){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var loginName=$("#tfa_j_username").val();
|
var loginName=$("#mobile_j_username").val();
|
||||||
if(loginName==""){
|
if(loginName==""){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.get("<@base />/login/otp/"+loginName,function(data,status){
|
$.get("<@base />/login/sendsms/"+loginName,function(data,status){
|
||||||
alert("Data: " + data + "\nStatus: " + status);
|
//alert("Data: " + data + "\nStatus: " + status);
|
||||||
});
|
});
|
||||||
|
|
||||||
<#--todo:send captcha-->
|
<#--todo:send captcha-->
|
||||||
@ -190,158 +175,36 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<ul id="switch_tab" class="switch_tab">
|
<ul id="switch_tab" class="switch_tab">
|
||||||
<li id="switch_commonLogin" value="div_commonLogin" class="switch_tab_class switch_tab_current"><a href="javascript:void(0);">
|
<li id="normalLogin" class="switch_tab_class switch_tab_current">
|
||||||
<@locale code="login.text.login.normal"/></a></li>
|
<a href="javascript:void(0);">
|
||||||
<li id="switch_tfaLogin" value="div_tfaLogin" class="switch_tab_class"><a href="javascript:void(0);">
|
<@locale code="login.text.login.normal"/>
|
||||||
<@locale code="login.text.login.twofactor"/></a></li>
|
</a>
|
||||||
|
</li>
|
||||||
|
<!--
|
||||||
|
<li id="tfaLogin" class="switch_tab_class">
|
||||||
|
<a href="javascript:void(0);">
|
||||||
|
<@locale code="login.text.login.twofactor"/>
|
||||||
|
</a>
|
||||||
|
</li>-->
|
||||||
|
<!---->
|
||||||
|
<li id="mobileLogin" class="switch_tab_class">
|
||||||
|
<a href="javascript:void(0);">
|
||||||
|
<@locale code="login.text.login.mobile"/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div id="div_commonLogin" >
|
<div id="div_normalLogin" >
|
||||||
<form id="loginForm" name="loginForm" action="<@base />/logon.do" method="post" class="needs-validation" novalidate>
|
<#include "loginnormal.ftl">
|
||||||
<input type="hidden" name="authType" value="basic"/>
|
|
||||||
<table class="table login_form_table">
|
|
||||||
<tr class="loginErrorMessage" <#if ''==loginErrorMessage>style="display:none;"</#if>>
|
|
||||||
<td colspan="2" style="color:red;">
|
|
||||||
${loginErrorMessage!}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.username"/>:</td>
|
|
||||||
<td>
|
|
||||||
<div class="wrapper">
|
|
||||||
<i class="fa fa-user"></i>
|
|
||||||
<input required="" class="form-control" type='text' id='j_username' name='username' value="admin" tabindex="1"/>
|
|
||||||
</div >
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.password"/>:</td>
|
|
||||||
<td>
|
|
||||||
<div class="wrapper">
|
|
||||||
<i class="fa fa-key fa-2" style="color: #FFD700;"></i>
|
|
||||||
<input required="" class="form-control" type='password' id='j_password' name='password' value="maxkey" tabindex="2"/>
|
|
||||||
</div >
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<#if true==isCaptcha>
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.captcha"/>:</td>
|
|
||||||
<td>
|
|
||||||
<div class="wrapper">
|
|
||||||
<i class="fa fa-lock fa-2"></i>
|
|
||||||
<input required="" class="form-control " type='text' id="j_captcha" name="captcha" tabindex="3" value="" style="float: left;"/><img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha"/>
|
|
||||||
</div >
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</#if>
|
|
||||||
<#if true==isRemeberMe>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<table style="width:100%">
|
|
||||||
<tr>
|
|
||||||
<td style="width:50%">
|
|
||||||
<span class="form_checkbox_label">
|
|
||||||
<input type='checkbox' id="remeberMe" name="remeberMe" class="checkbox" tabindex="4" value="remeberMe" />
|
|
||||||
<@locale code="login.text.remeberme"/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style="width:50%"><a href="<@base />/forgotpassword/forward"><@locale code="login.text.forgotpassword"/></a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</#if>
|
|
||||||
<tr style="display:none">
|
|
||||||
<td>sessionid:</td>
|
|
||||||
<td><input class="form-control" type='text' id="j_sessionid" name="sessionId" value="${sessionid}" /></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr >
|
|
||||||
<td colspan="2">
|
|
||||||
<input type="submit" id="loginSubmitButton" style="display: none;" />
|
|
||||||
<input id="loginSubmit" type="button" tabindex="5" style="width: 100%;" class="button btn btn-lg btn-primary btn-block" value="<@locale code="login.button.login"/>"/></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="div_tfaLogin" >
|
<div id="div_tfaLogin" >
|
||||||
<form id="tfaLoginForm" name="tfaLoginForm" action="<@base />/logon.do" method="post" class="needs-validation" novalidate>
|
<#include "logintfa.ftl">
|
||||||
<input type="hidden" name="authType" value="tfa"/>
|
</div>
|
||||||
<table class="login_form_table">
|
<div id="div_mobileLogin" >
|
||||||
<tr class="loginErrorMessage" <#if ''==loginErrorMessage>style="display:none;"</#if>>
|
<#include "loginmobile.ftl">
|
||||||
<td colspan="2" style="color:red;">
|
|
||||||
${loginErrorMessage!}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.username"/>:</td>
|
|
||||||
<td><input required="" class="form-control" type='text' id='tfa_j_username' name='username' value="" tabindex="1"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<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>
|
|
||||||
</tr>
|
|
||||||
<#if true==isMfa >
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.captcha"/>:</td>
|
|
||||||
<td>
|
|
||||||
<input required="" class="form-control" type='text' id="tfa_j_otp_captcha" name="otpCaptcha" tabindex="3" value="" style="float: left;"/>
|
|
||||||
<input class="form-control" id="tfa_j_otp_captcha_button" type="button" tabindex="5" class="button" value="获取动态验证码"/>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<#if "TOPT"==otpType >
|
|
||||||
<tr>
|
|
||||||
<td><@locale code="login.text.currenttime"/>:</td>
|
|
||||||
<td>
|
|
||||||
<input class="form-control" readonly type='text' id="currentTime" name="currentTime" tabindex="3" value="" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</#if>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<div id="currentTime"></div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</#if>
|
|
||||||
<#if true==isRemeberMe>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<table style="width:100%">
|
|
||||||
<tr>
|
|
||||||
<td style="width:50%">
|
|
||||||
<span class="form_checkbox_label">
|
|
||||||
<input type='checkbox' id="tfa_remeberMe" name="remeberMe" class="checkbox" tabindex="4" value="remeberMe" />
|
|
||||||
<@locale code="login.text.remeberme"/>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td style="width:50%"><a href="<@base />/forgotpassword/forward"><@locale code="login.text.forgotpassword"/></a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</#if>
|
|
||||||
<tr style="display:none">
|
|
||||||
<td>sessionid:</td>
|
|
||||||
<td><input class="form-control" type='text' id="tfa_sessionid" name="sessionId" value="${sessionid}" /></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr >
|
|
||||||
<td colspan="2">
|
|
||||||
<input type="submit" id="tfaLoginSubmitButton" style="display: none;" />
|
|
||||||
<input id="tfa_loginSubmit" type="button" style="width: 100%;" tabindex="5" class="button btn btn-lg btn-primary btn-block" value="<@locale code="login.button.login"/>"/></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
<form id="mobileLoginForm" name="mobileLoginForm" action="<@base />/logon.do" method="post" class="needs-validation" novalidate>
|
||||||
|
<input type="hidden" name="authType" value="mobile"/>
|
||||||
|
<table class="login_form_table">
|
||||||
|
<tr class="loginErrorMessage" <#if ''==loginErrorMessage>style="display:none;"</#if>>
|
||||||
|
<td colspan="2" style="color:red;">
|
||||||
|
${loginErrorMessage!}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.mobile"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-mobile"></i>
|
||||||
|
<input required="" class="form-control" type='text' id='mobile_j_username' name='username' value="" tabindex="1"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.smscode"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-lock fa-2"></i>
|
||||||
|
<input required="" class="form-control" type='password' id='mobile_j_password' name='password' value="" tabindex="2" style="float: left;"/>
|
||||||
|
<input class="form-control" id="mobile_j_otp_captcha_button" type="button" tabindex="5" class="button" value="<@locale code="login.text.login.mobile.obtain"/>"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<#if true==isRemeberMe>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<table style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<td style="width:50%">
|
||||||
|
<span class="form_checkbox_label">
|
||||||
|
<input type='checkbox' id="mobile_remeberMe" name="remeberMe" class="checkbox" tabindex="4" value="remeberMe" />
|
||||||
|
<@locale code="login.text.remeberme"/>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="width:50%"><a href="<@base />/forgotpassword/forward"><@locale code="login.text.forgotpassword"/></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<tr style="display:none">
|
||||||
|
<td>sessionid:</td>
|
||||||
|
<td><input class="form-control" type='text' id="mobile_sessionid" name="sessionId" value="${sessionid}" /></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr >
|
||||||
|
<td colspan="2">
|
||||||
|
<input type="submit" id="mobileLoginSubmitButton" style="display: none;" />
|
||||||
|
<input id="mobileLoginSubmit" type="button" style="width: 100%;" tabindex="5" class="doLoginSubmit button btn btn-lg btn-primary btn-block" value="<@locale code="login.button.login"/>"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</form>
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
<form id="normalLoginForm" name="normalLoginForm" action="<@base />/logon.do" method="post" class="needs-validation" novalidate>
|
||||||
|
<input type="hidden" name="authType" value="normal"/>
|
||||||
|
<table class="table login_form_table">
|
||||||
|
<tr class="loginErrorMessage" <#if ''==loginErrorMessage>style="display:none;"</#if>>
|
||||||
|
<td colspan="2" style="color:red;">
|
||||||
|
${loginErrorMessage!}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.username"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-user"></i>
|
||||||
|
<input required="" class="form-control" type='text' id='j_username' name='username' value="admin" tabindex="1"/>
|
||||||
|
</div >
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.password"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-key fa-2" style="color: #FFD700;"></i>
|
||||||
|
<input required="" class="form-control" type='password' id='j_password' name='password' value="maxkey" tabindex="2"/>
|
||||||
|
</div >
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<#if true==isCaptcha>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.captcha"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-lock fa-2"></i>
|
||||||
|
<input required="" class="form-control " type='text' id="j_captcha" name="captcha" tabindex="3" value="" style="float: left;"/><img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha"/>
|
||||||
|
</div >
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<#if true==isRemeberMe>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<table style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<td style="width:50%">
|
||||||
|
<span class="form_checkbox_label">
|
||||||
|
<input type='checkbox' id="remeberMe" name="remeberMe" class="checkbox" tabindex="4" value="remeberMe" />
|
||||||
|
<@locale code="login.text.remeberme"/>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="width:50%"><a href="<@base />/forgotpassword/forward"><@locale code="login.text.forgotpassword"/></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<tr style="display:none">
|
||||||
|
<td>sessionid:</td>
|
||||||
|
<td><input class="form-control" type='text' id="j_sessionid" name="sessionId" value="${sessionid}" /></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr >
|
||||||
|
<td colspan="2">
|
||||||
|
<input type="submit" id="normalLoginSubmitButton" style="display: none;" />
|
||||||
|
<input id="normalLoginSubmit" type="button" tabindex="5" style="width: 100%;" class="doLoginSubmit button btn btn-lg btn-primary btn-block" value="<@locale code="login.button.login"/>"/></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</form>
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
<form id="tfaLoginForm" name="tfaLoginForm" action="<@base />/logon.do" method="post" class="needs-validation" novalidate>
|
||||||
|
<input type="hidden" name="authType" value="tfa"/>
|
||||||
|
<table class="login_form_table">
|
||||||
|
<tr class="loginErrorMessage" <#if ''==loginErrorMessage>style="display:none;"</#if>>
|
||||||
|
<td colspan="2" style="color:red;">
|
||||||
|
${loginErrorMessage!}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.username"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-user"></i>
|
||||||
|
<input required="" class="form-control" type='text' id='tfa_j_username' name='username' value="" tabindex="1"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.password"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-key fa-2" style="color: #FFD700;"></i>
|
||||||
|
<input required="" class="form-control" type='password' id='tfa_j_password' name='password' value="" tabindex="2" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<#if true==isMfa >
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.captcha"/>:</td>
|
||||||
|
<td>
|
||||||
|
<div class="wrapper">
|
||||||
|
<i class="fa fa-lock fa-2"></i>
|
||||||
|
<input required="" class="form-control" type='text' id="tfa_j_otp_captcha" name="otpCaptcha" tabindex="3" value="" style="float: left;"/>
|
||||||
|
<input class="form-control" id="tfa_j_otp_captcha_button" type="button" tabindex="5" class="button" value="<@locale code="login.text.login.twofactor.obtain"/>"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<#if "TOPT"==otpType >
|
||||||
|
<tr>
|
||||||
|
<td><@locale code="login.text.currenttime"/>:</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" readonly type='text' id="currentTime" name="currentTime" tabindex="3" value="" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<div id="currentTime"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<#if true==isRemeberMe>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<table style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<td style="width:50%">
|
||||||
|
<span class="form_checkbox_label">
|
||||||
|
<input type='checkbox' id="tfa_remeberMe" name="remeberMe" class="checkbox" tabindex="4" value="remeberMe" />
|
||||||
|
<@locale code="login.text.remeberme"/>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="width:50%"><a href="<@base />/forgotpassword/forward"><@locale code="login.text.forgotpassword"/></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
<tr style="display:none">
|
||||||
|
<td>sessionid:</td>
|
||||||
|
<td><input class="form-control" type='text' id="tfa_sessionid" name="sessionId" value="${sessionid}" /></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr >
|
||||||
|
<td colspan="2">
|
||||||
|
<input type="submit" id="tfaLoginSubmitButton" style="display: none;" />
|
||||||
|
<input id="tfaLoginSubmit" type="button" style="width: 100%;" tabindex="5" class="doLoginSubmit button btn btn-lg btn-primary btn-block" value="<@locale code="login.button.login"/>"/></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="clear"></div>
|
||||||
|
</form>
|
||||||
Loading…
x
Reference in New Issue
Block a user