This commit is contained in:
Crystal.Sea
2021-01-06 23:46:44 +08:00
parent fbb401a9e0
commit 652083494e
4 changed files with 40 additions and 148 deletions

View File

@@ -142,5 +142,12 @@ public abstract class AbstractOptAuthn {
this.optType = optType;
}
public void setOptTokenStore(AbstractOptTokenStore optTokenStore) {
this.optTokenStore = optTokenStore;
}
public void initPropertys() {
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.crypto.password.opt.token;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.maxkey.constants.ConstantsStatus;
import org.maxkey.crypto.password.opt.OneTimePassword;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class JdbcOptTokenStore extends AbstractOptTokenStore {
private static final Logger logger = LoggerFactory.getLogger(JdbcOptTokenStore.class);
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT =
"INSERT INTO ONE_TIME_PASSWORD(ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME,STATUS)"
+ " VALUES(?,?,?,?,?,?," + ConstantsStatus.ACTIVE + ")";
private static final String DEFAULT_DEFAULT_SELECT_STATEMENT =
"SELECT ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME FROM ONE_TIME_PASSWORD"
+ " WHERE STATUS =" + ConstantsStatus.ACTIVE
+ " AND USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT =
"UPDATE ONE_TIME_PASSWORD SET STATUS ="
+ ConstantsStatus.DELETE + " WHERE USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
private final JdbcTemplate jdbcTemplate;
public JdbcOptTokenStore(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
*store.
*/
public void store(UserInfo userInfo, String token, String receiver, String type) {
jdbcTemplate.update(DEFAULT_DEFAULT_INSERT_STATEMENT,
new Object[] {
java.util.UUID.randomUUID(),
type,
userInfo.getUsername(),
token,
receiver,
new Date()
},
new int[] { Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR,Types.TIMESTAMP
}
);
}
/**
* validate.
* @param userInfo UserInfo
* @param token String
* @param type int
* @return
*/
public boolean validate(UserInfo userInfo, String token, String type,int interval) {
OneTimePassword oneTimePassword = jdbcTemplate.queryForObject(
DEFAULT_DEFAULT_SELECT_STATEMENT,
new OneTimePasswordRowMapper(), userInfo.getUsername(), token, type);
if (oneTimePassword != null) {
jdbcTemplate.update(
DEFAULT_DEFAULT_DELETE_STATEMENT,
new Object[] { userInfo.getUsername(), token, type },
new int[] { Types.VARCHAR, Types.VARCHAR, Types.INTEGER }
);
DateTime currentdateTime = new DateTime();
DateTime oneTimePwdData = DateTime.parse(oneTimePassword.getCreateTime(),
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Duration duration = new Duration(oneTimePwdData, currentdateTime);
int intDuration = Integer.parseInt(duration.getStandardSeconds() + "");
logger.debug("validate duration " + intDuration);
logger.debug("validate result " + (intDuration <= interval));
if (intDuration <= interval) {
return true;
}
}
return false;
}
public class OneTimePasswordRowMapper implements RowMapper<OneTimePassword> {
/**
*ResultSet.
*/
public OneTimePassword mapRow(ResultSet rs, int rowNum) throws SQLException {
OneTimePassword oneTimePassword = new OneTimePassword();
oneTimePassword.setId(rs.getString("ID"));
oneTimePassword.setType(rs.getString("OPTTYPE"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setToken(rs.getString("TOKEN"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setReceiver(rs.getString("RECEIVER"));
oneTimePassword.setCreateTime(rs.getString("CREATETIME"));
return oneTimePassword;
}
}
}

View File

@@ -30,6 +30,11 @@ public class RedisOptTokenStore extends AbstractOptTokenStore {
RedisConnectionFactory connectionFactory;
public RedisOptTokenStore(RedisConnectionFactory connectionFactory) {
super();
this.connectionFactory = connectionFactory;
}
public static String PREFIX = "REDIS_OTP_SERVICE_";
@Override

View File

@@ -27,6 +27,7 @@ import org.maxkey.authn.realm.activedirectory.ActiveDirectoryAuthenticationRealm
import org.maxkey.authn.realm.activedirectory.ActiveDirectoryServer;
import org.maxkey.authn.support.kerberos.KerberosProxy;
import org.maxkey.authn.support.kerberos.RemoteKerberosService;
import org.maxkey.constants.ConstantsPersistence;
import org.maxkey.constants.ConstantsProperties;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.crypto.password.opt.algorithm.KeyUriFormat;
@@ -36,14 +37,15 @@ 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.token.RedisOptTokenStore;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils;
import org.maxkey.persistence.redis.RedisConnectionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -51,8 +53,6 @@ import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
//@ImportResource(locations = { "classpath:spring/maxkey.xml" })
@PropertySource(ConstantsProperties.applicationPropertySource)
@@ -160,31 +160,35 @@ public class MaxKeyConfig implements InitializingBean {
@Bean(name = "tfaOptAuthn")
public AbstractOptAuthn tfaOptAuthn(
@Value("${config.login.mfa.type}")String mfaType,
MailOtpAuthn tfaMailOptAuthn) {
@Value("${config.server.persistence}") int persistence,
MailOtpAuthn tfaMailOptAuthn,
RedisConnectionFactory redisConnFactory) {
AbstractOptAuthn tfaOptAuthn = null;
if(mfaType.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
SmsOtpAuthnAliyun tfaOptAuthn = new SmsOtpAuthnAliyun();
tfaOptAuthn.initPropertys();
tfaOptAuthn = new SmsOtpAuthnAliyun();
_logger.debug("SmsOtpAuthnAliyun inited.");
return tfaOptAuthn;
}else if(mfaType.equalsIgnoreCase("SmsOtpAuthnTencentCloud")) {
SmsOtpAuthnTencentCloud tfaOptAuthn = new SmsOtpAuthnTencentCloud();
tfaOptAuthn.initPropertys();
tfaOptAuthn = new SmsOtpAuthnTencentCloud();
_logger.debug("SmsOtpAuthnTencentCloud inited.");
return tfaOptAuthn;
}else if(mfaType.equalsIgnoreCase("SmsOtpAuthnYunxin")) {
SmsOtpAuthnYunxin tfaOptAuthn = new SmsOtpAuthnYunxin();
tfaOptAuthn.initPropertys();
tfaOptAuthn = new SmsOtpAuthnYunxin();
_logger.debug("SmsOtpAuthnYunxin inited.");
return tfaOptAuthn;
}else if(mfaType.equalsIgnoreCase("MailOtpAuthn")) {
tfaOptAuthn = tfaMailOptAuthn;
_logger.debug("MailOtpAuthn inited.");
return tfaMailOptAuthn;
}else {
TimeBasedOtpAuthn tfaOptAuthn = new TimeBasedOtpAuthn();
tfaOptAuthn = new TimeBasedOtpAuthn();
_logger.debug("TimeBasedOtpAuthn inited.");
return tfaOptAuthn;
}
if (persistence == ConstantsPersistence.REDIS) {
RedisOptTokenStore redisOptTokenStore = new RedisOptTokenStore(redisConnFactory);
tfaOptAuthn.setOptTokenStore(redisOptTokenStore);
}
tfaOptAuthn.initPropertys();
return tfaOptAuthn;
}
@Bean(name = "tfaMailOptAuthn")
@@ -202,9 +206,11 @@ public class MaxKeyConfig implements InitializingBean {
}
@Bean(name = "tfaMobileOptAuthn")
public SmsOtpAuthn smsOtpAuthn(@Value("${config.otp.sms}")String optSmsProvider) {
public SmsOtpAuthn smsOtpAuthn(
@Value("${config.otp.sms}")String optSmsProvider,
@Value("${config.server.persistence}") int persistence,
RedisConnectionFactory redisConnFactory) {
SmsOtpAuthn smsOtpAuthn = null;
if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnAliyun")) {
smsOtpAuthn = new SmsOtpAuthnAliyun();
}else if(optSmsProvider.equalsIgnoreCase("SmsOtpAuthnTencentCloud")) {
@@ -212,6 +218,10 @@ public class MaxKeyConfig implements InitializingBean {
}else {
smsOtpAuthn = new SmsOtpAuthnYunxin();
}
if (persistence == ConstantsPersistence.REDIS) {
RedisOptTokenStore redisOptTokenStore = new RedisOptTokenStore(redisConnFactory);
smsOtpAuthn.setOptTokenStore(redisOptTokenStore);
}
smsOtpAuthn.initPropertys();
_logger.debug("SmsOtpAuthn inited.");