OtpAuthn
This commit is contained in:
@@ -142,5 +142,12 @@ public abstract class AbstractOptAuthn {
|
||||
this.optType = optType;
|
||||
}
|
||||
|
||||
public void setOptTokenStore(AbstractOptTokenStore optTokenStore) {
|
||||
this.optTokenStore = optTokenStore;
|
||||
}
|
||||
|
||||
public void initPropertys() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
Reference in New Issue
Block a user