LDAP password sync

This commit is contained in:
MaxKey
2021-07-22 22:15:21 +08:00
parent fae33d2be6
commit 233307f366
10 changed files with 38 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
#maxkey properties #maxkey properties
group =maxkey.top group =maxkey.top
version =2.8.1 version =2.8.2
vendor =https://www.maxkey.top vendor =https://www.maxkey.top
author =MaxKeyTop author =MaxKeyTop
#maxkey used jars version #maxkey used jars version

View File

@@ -26,6 +26,7 @@ import org.maxkey.entity.Groups;
import org.maxkey.entity.UserInfo; import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.db.LoginHistoryService; import org.maxkey.persistence.db.LoginHistoryService;
import org.maxkey.persistence.db.PasswordPolicyValidator; import org.maxkey.persistence.db.PasswordPolicyValidator;
import org.maxkey.persistence.service.UserInfoService;
import org.maxkey.persistence.db.LoginService; import org.maxkey.persistence.db.LoginService;
import org.maxkey.util.DateUtils; import org.maxkey.util.DateUtils;
import org.maxkey.web.WebConstants; import org.maxkey.web.WebConstants;
@@ -59,6 +60,8 @@ public abstract class AbstractAuthenticationRealm {
protected AbstractAuthenticationRealm ldapAuthenticationRealm; protected AbstractAuthenticationRealm ldapAuthenticationRealm;
protected UserInfoService userInfoService;
/** /**

View File

@@ -53,13 +53,25 @@ public class DefaultJdbcAuthenticationRealm extends AbstractAuthenticationRealm
*/ */
public boolean passwordMatches(UserInfo userInfo, String password) { public boolean passwordMatches(UserInfo userInfo, String password) {
boolean passwordMatches = false; boolean passwordMatches = false;
if(ldapSupport) { //jdbc password check
_logger.debug("password : "
+ PasswordReciprocal.getInstance().rawPassword(userInfo.getUsername(), password));
passwordMatches = passwordEncoder.matches(password,userInfo.getPassword());
//passwordMatches == false and ldapSupport ==true
//validate password with LDAP
if(!passwordMatches && ldapSupport) {
passwordMatches =this.ldapAuthenticationRealm.passwordMatches(userInfo, password); passwordMatches =this.ldapAuthenticationRealm.passwordMatches(userInfo, password);
}else { if(passwordMatches) {
_logger.debug("password : " //init password to local Realm
+ PasswordReciprocal.getInstance().rawPassword(userInfo.getUsername(), password)); UserInfo changePasswordUser = new UserInfo();
passwordMatches = passwordEncoder.matches(password,userInfo.getPassword()); changePasswordUser.setId(userInfo.getId());
changePasswordUser.setUsername(userInfo.getUsername());
changePasswordUser.setPassword(password);
userInfoService.changePassword(changePasswordUser, false);
}
} }
_logger.debug("passwordvalid : " + passwordMatches); _logger.debug("passwordvalid : " + passwordMatches);
if (!passwordMatches) { if (!passwordMatches) {
passwordPolicyValidator.setBadPasswordCount(userInfo); passwordPolicyValidator.setBadPasswordCount(userInfo);

View File

@@ -22,6 +22,7 @@ import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
import org.maxkey.persistence.db.LoginHistoryService; import org.maxkey.persistence.db.LoginHistoryService;
import org.maxkey.persistence.db.LoginService; import org.maxkey.persistence.db.LoginService;
import org.maxkey.persistence.db.PasswordPolicyValidator; import org.maxkey.persistence.db.PasswordPolicyValidator;
import org.maxkey.persistence.service.UserInfoService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@@ -49,6 +50,7 @@ public class JdbcAuthenticationRealm extends DefaultJdbcAuthenticationRealm {
LoginService loginService, LoginService loginService,
LoginHistoryService loginHistoryService, LoginHistoryService loginHistoryService,
AbstractRemeberMeService remeberMeService, AbstractRemeberMeService remeberMeService,
UserInfoService userInfoService,
JdbcTemplate jdbcTemplate) { JdbcTemplate jdbcTemplate) {
this.passwordEncoder =passwordEncoder; this.passwordEncoder =passwordEncoder;
@@ -56,6 +58,7 @@ public class JdbcAuthenticationRealm extends DefaultJdbcAuthenticationRealm {
this.loginService = loginService; this.loginService = loginService;
this.loginHistoryService = loginHistoryService; this.loginHistoryService = loginHistoryService;
this.remeberMeService = remeberMeService; this.remeberMeService = remeberMeService;
this.userInfoService = userInfoService;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
} }
@@ -66,6 +69,7 @@ public class JdbcAuthenticationRealm extends DefaultJdbcAuthenticationRealm {
LoginService loginService, LoginService loginService,
LoginHistoryService loginHistoryService, LoginHistoryService loginHistoryService,
AbstractRemeberMeService remeberMeService, AbstractRemeberMeService remeberMeService,
UserInfoService userInfoService,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
AbstractAuthenticationRealm ldapAuthenticationRealm, AbstractAuthenticationRealm ldapAuthenticationRealm,
boolean ldapSupport boolean ldapSupport
@@ -78,6 +82,7 @@ public class JdbcAuthenticationRealm extends DefaultJdbcAuthenticationRealm {
this.remeberMeService = remeberMeService; this.remeberMeService = remeberMeService;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.ldapAuthenticationRealm = ldapAuthenticationRealm; this.ldapAuthenticationRealm = ldapAuthenticationRealm;
this.userInfoService = userInfoService;
this.ldapSupport = ldapSupport; this.ldapSupport = ldapSupport;
} }

View File

@@ -80,7 +80,7 @@ public class RestUserInfoController {
changePassword.setUsername(username); changePassword.setUsername(username);
changePassword.setPassword(password); changePassword.setPassword(password);
changePassword.setDecipherable(loadUserInfo.getDecipherable()); changePassword.setDecipherable(loadUserInfo.getDecipherable());
userInfoService.changePassword(changePassword); userInfoService.changePassword(changePassword,true);
} }
return "true"; return "true";
} }

View File

@@ -229,7 +229,7 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
if(newPassword.equals(confirmPassword)){ if(newPassword.equals(confirmPassword)){
if(oldPassword==null || if(oldPassword==null ||
passwordEncoder.matches(oldPassword, userInfo.getPassword())){ passwordEncoder.matches(oldPassword, userInfo.getPassword())){
if(changePassword(changeUserInfo) ){ if(changePassword(changeUserInfo,true) ){
userInfo.setPassword(changeUserInfo.getPassword()); userInfo.setPassword(changeUserInfo.getPassword());
userInfo.setDecipherable(changeUserInfo.getDecipherable()); userInfo.setDecipherable(changeUserInfo.getDecipherable());
return true; return true;
@@ -256,19 +256,18 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
return false; return false;
} }
public boolean changePassword(UserInfo changeUserInfo) { public boolean changePassword(UserInfo changeUserInfo,boolean passwordPolicy) {
try { try {
_logger.debug("decipherable old : " + changeUserInfo.getDecipherable()); _logger.debug("decipherable old : " + changeUserInfo.getDecipherable());
_logger.debug("decipherable new : " + ReciprocalUtils.encode(PasswordReciprocal.getInstance() _logger.debug("decipherable new : " + ReciprocalUtils.encode(PasswordReciprocal.getInstance()
.rawPassword(changeUserInfo.getUsername(), changeUserInfo.getPassword()))); .rawPassword(changeUserInfo.getUsername(), changeUserInfo.getPassword())));
if (passwordPolicyValidator.validator(changeUserInfo) == false) { if (passwordPolicy && passwordPolicyValidator.validator(changeUserInfo) == false) {
return false; return false;
} }
if (WebContext.getUserInfo() != null) { if (WebContext.getUserInfo() != null) {
changeUserInfo.setModifiedBy(WebContext.getUserInfo().getId()); changeUserInfo.setModifiedBy(WebContext.getUserInfo().getId());
} }
changeUserInfo = passwordEncoder(changeUserInfo); changeUserInfo = passwordEncoder(changeUserInfo);

View File

@@ -33,6 +33,7 @@ import org.maxkey.persistence.db.LoginService;
import org.maxkey.persistence.db.PasswordPolicyValidator; import org.maxkey.persistence.db.PasswordPolicyValidator;
import org.maxkey.persistence.redis.RedisConnectionFactory; import org.maxkey.persistence.redis.RedisConnectionFactory;
import org.maxkey.persistence.service.GroupsService; import org.maxkey.persistence.service.GroupsService;
import org.maxkey.persistence.service.UserInfoService;
import org.opensaml.xml.ConfigurationException; import org.opensaml.xml.ConfigurationException;
import org.quartz.CronScheduleBuilder; import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger; import org.quartz.CronTrigger;
@@ -118,6 +119,7 @@ public class MaxKeyMgtConfig implements InitializingBean {
LoginService loginService, LoginService loginService,
LoginHistoryService loginHistoryService, LoginHistoryService loginHistoryService,
AbstractRemeberMeService remeberMeService, AbstractRemeberMeService remeberMeService,
UserInfoService userInfoService,
JdbcTemplate jdbcTemplate) { JdbcTemplate jdbcTemplate) {
JdbcAuthenticationRealm authenticationRealm = new JdbcAuthenticationRealm( JdbcAuthenticationRealm authenticationRealm = new JdbcAuthenticationRealm(
@@ -126,6 +128,7 @@ public class MaxKeyMgtConfig implements InitializingBean {
loginService, loginService,
loginHistoryService, loginHistoryService,
remeberMeService, remeberMeService,
userInfoService,
jdbcTemplate); jdbcTemplate);
_logger.debug("JdbcAuthenticationRealm inited."); _logger.debug("JdbcAuthenticationRealm inited.");

View File

@@ -264,7 +264,7 @@ public class UserInfoController {
@RequestMapping(value="/changePassword") @RequestMapping(value="/changePassword")
public Message changePassword( @ModelAttribute("userInfo")UserInfo userInfo) { public Message changePassword( @ModelAttribute("userInfo")UserInfo userInfo) {
_logger.debug(userInfo.getId()); _logger.debug(userInfo.getId());
if(userInfoService.changePassword(userInfo)) { if(userInfoService.changePassword(userInfo,true)) {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success); return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
} else { } else {

View File

@@ -48,6 +48,7 @@ import org.maxkey.persistence.db.PasswordPolicyValidator;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils; import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils; import org.maxkey.persistence.ldap.LdapUtils;
import org.maxkey.persistence.redis.RedisConnectionFactory; import org.maxkey.persistence.redis.RedisConnectionFactory;
import org.maxkey.persistence.service.UserInfoService;
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;
@@ -156,6 +157,7 @@ public class MaxKeyConfig implements InitializingBean {
LoginService loginService, LoginService loginService,
LoginHistoryService loginHistoryService, LoginHistoryService loginHistoryService,
AbstractRemeberMeService remeberMeService, AbstractRemeberMeService remeberMeService,
UserInfoService userInfoService,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
@Value("${maxkey.support.ldap.enable:false}")boolean ldapSupport, @Value("${maxkey.support.ldap.enable:false}")boolean ldapSupport,
@Value("${maxkey.support.ldap.jit:false}")boolean ldapJit, @Value("${maxkey.support.ldap.jit:false}")boolean ldapJit,
@@ -179,6 +181,7 @@ public class MaxKeyConfig implements InitializingBean {
loginService, loginService,
loginHistoryService, loginHistoryService,
remeberMeService, remeberMeService,
userInfoService,
jdbcTemplate, jdbcTemplate,
ldapAuthenticationRealm, ldapAuthenticationRealm,
ldapSupport ldapSupport

View File

@@ -129,7 +129,7 @@ public class ForgotPasswordContorller {
if ((forgotType == ForgotType.EMAIL && mailOtpAuthn.validate(userInfo, captcha)) || if ((forgotType == ForgotType.EMAIL && mailOtpAuthn.validate(userInfo, captcha)) ||
(forgotType == ForgotType.MOBILE && smsOtpAuthn.validate(userInfo, captcha)) (forgotType == ForgotType.MOBILE && smsOtpAuthn.validate(userInfo, captcha))
) { ) {
userInfoService.changePassword(userInfo); userInfoService.changePassword(userInfo,true);
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS); modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
} else { } else {
modelAndView.addObject("passwordResetResult", PasswordResetResult.CAPTCHAERROR); modelAndView.addObject("passwordResetResult", PasswordResetResult.CAPTCHAERROR);