mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-06-07 09:44:03 +08:00
LDAP学员同步
This commit is contained in:
parent
8c905c6552
commit
040dcdfaed
@ -23,14 +23,12 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import xyz.playedu.api.event.UserLoginEvent;
|
||||
import xyz.playedu.common.domain.LdapUser;
|
||||
import xyz.playedu.common.bus.LDAPBus;
|
||||
import xyz.playedu.common.domain.User;
|
||||
import xyz.playedu.common.exception.ServiceException;
|
||||
import xyz.playedu.common.service.*;
|
||||
import xyz.playedu.common.util.HelperUtil;
|
||||
import xyz.playedu.common.util.IpUtil;
|
||||
import xyz.playedu.common.util.RequestUtil;
|
||||
import xyz.playedu.common.util.StringUtil;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -41,14 +39,10 @@ public class LoginBus {
|
||||
|
||||
@Autowired private FrontendAuthService authService;
|
||||
|
||||
@Autowired private DepartmentService departmentService;
|
||||
|
||||
@Autowired private LdapUserService ldapUserService;
|
||||
|
||||
@Autowired private UserService userService;
|
||||
|
||||
@Autowired private AppConfigService appConfigService;
|
||||
|
||||
@Autowired private LDAPBus ldapBus;
|
||||
|
||||
@Autowired private ApplicationContext ctx;
|
||||
|
||||
public HashMap<String, Object> tokenByUser(User user) {
|
||||
@ -72,72 +66,7 @@ public class LoginBus {
|
||||
@Transactional
|
||||
public HashMap<String, Object> tokenByLdapTransformUser(LdapTransformUser ldapTransformUser)
|
||||
throws ServiceException {
|
||||
// LDAP用户的名字
|
||||
String ldapUserName = ldapTransformUser.getCn();
|
||||
|
||||
// 将LDAP用户所属的部门同步到本地
|
||||
Integer depId = departmentService.createWithChainList(ldapTransformUser.getOu());
|
||||
Integer[] depIds = depId == 0 ? null : new Integer[] {depId};
|
||||
|
||||
// LDAP用户在本地的缓存记录
|
||||
LdapUser ldapUser = ldapUserService.findByUUID(ldapTransformUser.getId());
|
||||
User user;
|
||||
|
||||
// 计算将LDAP用户关联到本地users表的email字段值
|
||||
String localUserEmail = ldapTransformUser.getUid();
|
||||
if (StringUtil.isNotEmpty(ldapTransformUser.getEmail())) {
|
||||
localUserEmail = ldapTransformUser.getEmail();
|
||||
}
|
||||
|
||||
if (ldapUser == null) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
throw new ServiceException(String.format("已有其它账号在使用:%s", localUserEmail));
|
||||
}
|
||||
// LDAP用户数据缓存到本地
|
||||
ldapUser = ldapUserService.store(ldapTransformUser);
|
||||
// 创建本地user
|
||||
user =
|
||||
userService.createWithDepIds(
|
||||
localUserEmail,
|
||||
ldapUserName,
|
||||
appConfigService.defaultAvatar(),
|
||||
HelperUtil.randomString(20),
|
||||
"",
|
||||
depIds);
|
||||
// 将LDAP缓存数据与本地user关联
|
||||
ldapUserService.updateUserId(ldapUser.getId(), user.getId());
|
||||
} else {
|
||||
user = userService.find(ldapUser.getUserId());
|
||||
// 账号修改[账号有可能是email也有可能是uid]
|
||||
if (!localUserEmail.equals(user.getEmail())) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
throw new ServiceException(String.format("已有其它账号在使用:%s", localUserEmail));
|
||||
}
|
||||
userService.updateEmail(user.getId(), localUserEmail);
|
||||
}
|
||||
// ldap-email的变化
|
||||
if (!ldapUser.getEmail().equals(ldapTransformUser.getEmail())) {
|
||||
ldapUserService.updateEmail(ldapUser.getId(), ldapTransformUser.getEmail());
|
||||
}
|
||||
// ldap-uid的变化
|
||||
if (!ldapUser.getUid().equals(ldapTransformUser.getUid())) {
|
||||
ldapUserService.updateUid(ldapUser.getId(), ldapTransformUser.getUid());
|
||||
}
|
||||
// 名字同步修改
|
||||
if (!ldapUserName.equals(ldapUser.getCn())) {
|
||||
userService.updateName(user.getId(), ldapUserName);
|
||||
ldapUserService.updateCN(ldapUser.getId(), ldapUserName);
|
||||
}
|
||||
// 部门修改同步
|
||||
String newOU = String.join(",", ldapTransformUser.getOu());
|
||||
if (!newOU.equals(ldapUser.getOu())) {
|
||||
userService.updateDepId(user.getId(), depIds);
|
||||
ldapUserService.updateOU(ldapUser.getId(), newOU);
|
||||
}
|
||||
}
|
||||
|
||||
User user = ldapBus.singleUserSync(ldapTransformUser, appConfigService.defaultAvatar());
|
||||
return tokenByUser(user);
|
||||
}
|
||||
}
|
||||
|
@ -316,4 +316,13 @@ public class DepartmentController {
|
||||
ldapBus.departmentSync();
|
||||
return JsonResponse.success();
|
||||
}
|
||||
|
||||
@BackendPermission(slug = BPermissionConstant.DEPARTMENT_CUD)
|
||||
@PostMapping("/ldap-user-sync")
|
||||
@Log(title = "部门-LDAP学员同步", businessType = BusinessTypeConstant.INSERT)
|
||||
@SneakyThrows
|
||||
public JsonResponse ldapUserSync() {
|
||||
ldapBus.userSync();
|
||||
return JsonResponse.success();
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,15 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import xyz.playedu.common.domain.Department;
|
||||
import xyz.playedu.common.domain.LdapDepartment;
|
||||
import xyz.playedu.common.domain.LdapUser;
|
||||
import xyz.playedu.common.domain.User;
|
||||
import xyz.playedu.common.exception.NotFoundException;
|
||||
import xyz.playedu.common.service.AppConfigService;
|
||||
import xyz.playedu.common.service.DepartmentService;
|
||||
import xyz.playedu.common.service.LdapDepartmentService;
|
||||
import xyz.playedu.common.service.*;
|
||||
import xyz.playedu.common.types.LdapConfig;
|
||||
import xyz.playedu.common.util.HelperUtil;
|
||||
import xyz.playedu.common.util.StringUtil;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformDepartment;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
import xyz.playedu.common.util.ldap.LdapUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -47,6 +50,10 @@ public class LDAPBus {
|
||||
|
||||
@Autowired private LdapDepartmentService ldapDepartmentService;
|
||||
|
||||
@Autowired private LdapUserService ldapUserService;
|
||||
|
||||
@Autowired private UserService userService;
|
||||
|
||||
public boolean enabledLDAP() {
|
||||
return appConfigService.enabledLdapLogin();
|
||||
}
|
||||
@ -149,5 +156,104 @@ public class LDAPBus {
|
||||
}
|
||||
}
|
||||
|
||||
public void userSync() {}
|
||||
public void userSync() throws NamingException {
|
||||
LdapConfig ldapConfig = appConfigService.ldapConfig();
|
||||
|
||||
List<LdapTransformUser> userList =
|
||||
LdapUtil.users(
|
||||
ldapConfig.getUrl(),
|
||||
ldapConfig.getAdminUser(),
|
||||
ldapConfig.getAdminPass(),
|
||||
ldapConfig.getBaseDN());
|
||||
|
||||
if (userList == null || userList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String defaultAvatar = appConfigService.defaultAvatar();
|
||||
|
||||
for (LdapTransformUser ldapTransformUser : userList) {
|
||||
singleUserSync(ldapTransformUser, defaultAvatar);
|
||||
}
|
||||
}
|
||||
|
||||
public User singleUserSync(LdapTransformUser ldapTransformUser, String defaultAvatar) {
|
||||
// LDAP用户的名字
|
||||
String ldapUserName = ldapTransformUser.getCn();
|
||||
|
||||
// 将LDAP用户所属的部门同步到本地
|
||||
Integer depId = departmentService.createWithChainList(ldapTransformUser.getOu());
|
||||
Integer[] depIds = depId == 0 ? null : new Integer[] {depId};
|
||||
|
||||
// LDAP用户在本地的缓存记录
|
||||
LdapUser ldapUser = ldapUserService.findByUUID(ldapTransformUser.getId());
|
||||
User user;
|
||||
|
||||
// 计算将LDAP用户关联到本地users表的email字段值
|
||||
String localUserEmail = ldapTransformUser.getUid();
|
||||
if (StringUtil.isNotEmpty(ldapTransformUser.getEmail())) {
|
||||
localUserEmail = ldapTransformUser.getEmail();
|
||||
}
|
||||
|
||||
if (ldapUser == null) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
localUserEmail = HelperUtil.randomString(5) + "_" + localUserEmail;
|
||||
}
|
||||
// LDAP用户数据缓存到本地
|
||||
ldapUser = ldapUserService.store(ldapTransformUser);
|
||||
// 创建本地user
|
||||
user =
|
||||
userService.createWithDepIds(
|
||||
localUserEmail,
|
||||
ldapUserName,
|
||||
defaultAvatar,
|
||||
HelperUtil.randomString(10),
|
||||
"",
|
||||
depIds);
|
||||
// 将LDAP缓存数据与本地user关联
|
||||
ldapUserService.updateUserId(ldapUser.getId(), user.getId());
|
||||
} else {
|
||||
user = userService.find(ldapUser.getUserId());
|
||||
if (user == null) {
|
||||
user =
|
||||
userService.createWithDepIds(
|
||||
localUserEmail,
|
||||
ldapUserName,
|
||||
defaultAvatar,
|
||||
HelperUtil.randomString(10),
|
||||
"",
|
||||
depIds);
|
||||
}
|
||||
// 账号修改[账号有可能是email也有可能是uid]
|
||||
if (!localUserEmail.equals(user.getEmail())) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
localUserEmail = HelperUtil.randomString(5) + "_" + localUserEmail;
|
||||
}
|
||||
userService.updateEmail(user.getId(), localUserEmail);
|
||||
}
|
||||
// ldap-email的变化
|
||||
if (!ldapUser.getEmail().equals(ldapTransformUser.getEmail())) {
|
||||
ldapUserService.updateEmail(ldapUser.getId(), ldapTransformUser.getEmail());
|
||||
}
|
||||
// ldap-uid的变化
|
||||
if (!ldapUser.getUid().equals(ldapTransformUser.getUid())) {
|
||||
ldapUserService.updateUid(ldapUser.getId(), ldapTransformUser.getUid());
|
||||
}
|
||||
// 名字同步修改
|
||||
if (!ldapUserName.equals(ldapUser.getCn())) {
|
||||
userService.updateName(user.getId(), ldapUserName);
|
||||
ldapUserService.updateCN(ldapUser.getId(), ldapUserName);
|
||||
}
|
||||
// 部门修改同步
|
||||
String newOU = String.join(",", ldapTransformUser.getOu());
|
||||
if (!newOU.equals(ldapUser.getOu())) {
|
||||
userService.updateDepId(user.getId(), depIds);
|
||||
ldapUserService.updateOU(ldapUser.getId(), newOU);
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
@ -48,14 +48,11 @@ public class LdapUtil {
|
||||
"entryUUID",
|
||||
|
||||
// Window AD 域的属性
|
||||
"memberOf",
|
||||
"name",
|
||||
"userPrincipalName",
|
||||
"departmentNumber",
|
||||
"telephoneNumber",
|
||||
"mobile",
|
||||
"department",
|
||||
"distinguishedName",
|
||||
"sAMAccountName",
|
||||
"displayName",
|
||||
"uSNCreated", // AD域的唯一属性
|
||||
|
||||
// 公用属性
|
||||
@ -76,8 +73,10 @@ public class LdapUtil {
|
||||
return new InitialLdapContext(context, null);
|
||||
}
|
||||
|
||||
public static List<HashMap<String, String>> users(LdapContext ldapContext, String baseDN)
|
||||
throws NamingException {
|
||||
public static List<LdapTransformUser> users(
|
||||
String url, String adminUser, String adminPass, String baseDN) throws NamingException {
|
||||
LdapContext ldapContext = initContext(url, adminUser, adminPass);
|
||||
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
controls.setReturningAttributes(USER_RETURN_ATTRS);
|
||||
@ -97,14 +96,14 @@ public class LdapUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<HashMap<String, String>> users = new ArrayList<>();
|
||||
List<LdapTransformUser> users = new ArrayList<>();
|
||||
while (result.hasMoreElements()) {
|
||||
SearchResult item = result.nextElement();
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
Attributes attributes = item.getAttributes();
|
||||
log.info("name={},attributes={}", item.getName(), attributes);
|
||||
LdapTransformUser ldapTransformUser = parseTransformUser(item, baseDN);
|
||||
users.add(ldapTransformUser);
|
||||
}
|
||||
|
||||
return users;
|
||||
@ -222,19 +221,51 @@ public class LdapUtil {
|
||||
}
|
||||
|
||||
// 根据mail或uid查询出来的用户
|
||||
SearchResult item = result.nextElement();
|
||||
Attributes attributes = item.getAttributes();
|
||||
LdapTransformUser ldapUser = parseTransformUser(result.nextElement(), baseDN);
|
||||
if (ldapUser == null) {
|
||||
log.info("LDAP-用户不存在");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 使用用户dn+提交的密码去登录ldap系统
|
||||
// 登录成功则意味着密码正确
|
||||
// 登录失败则意味着密码错误
|
||||
try {
|
||||
ldapContext = initContext(url, ldapUser.getDn() + "," + baseDN, password);
|
||||
return ldapUser;
|
||||
} catch (Exception e) {
|
||||
// 无法登录->密码错误
|
||||
log.error("LDAP-登录失败", e);
|
||||
return null;
|
||||
} finally {
|
||||
ldapContext.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static LdapTransformUser parseTransformUser(SearchResult item, String baseDN)
|
||||
throws NamingException {
|
||||
Attributes attributes = item.getAttributes();
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LdapTransformUser ldapUser = new LdapTransformUser();
|
||||
ldapUser.setDn(item.getName());
|
||||
|
||||
// name解析
|
||||
String displayName = (String) attributes.get("displayName").get();
|
||||
if (StringUtil.isEmpty(displayName)) {
|
||||
displayName = (String) attributes.get("cn").get();
|
||||
}
|
||||
ldapUser.setCn(displayName);
|
||||
|
||||
// 邮箱解析
|
||||
String email =
|
||||
attributes.get("mail") == null ? null : (String) attributes.get("mail").get();
|
||||
if (email == null) {
|
||||
email = attributes.get("email") == null ? null : (String) attributes.get("email").get();
|
||||
}
|
||||
|
||||
LdapTransformUser ldapUser = new LdapTransformUser();
|
||||
ldapUser.setDn(item.getName());
|
||||
ldapUser.setEmail(email);
|
||||
ldapUser.setCn((String) attributes.get("cn").get());
|
||||
|
||||
if (attributes.get("uSNCreated") != null) {
|
||||
// Window AD域
|
||||
@ -262,19 +293,7 @@ public class LdapUtil {
|
||||
Collections.reverse(ou);
|
||||
ldapUser.setOu(ou);
|
||||
|
||||
// 使用用户dn+提交的密码去登录ldap系统
|
||||
// 登录成功则意味着密码正确
|
||||
// 登录失败则意味着密码错误
|
||||
try {
|
||||
ldapContext = initContext(url, ldapUser.getDn() + "," + baseDN, password);
|
||||
return ldapUser;
|
||||
} catch (Exception e) {
|
||||
// 无法登录->密码错误
|
||||
log.error("LDAP-登录失败", e);
|
||||
return null;
|
||||
} finally {
|
||||
ldapContext.close();
|
||||
}
|
||||
return ldapUser;
|
||||
}
|
||||
|
||||
private static String baseDNOuScope(String baseDN) {
|
||||
@ -288,7 +307,7 @@ public class LdapUtil {
|
||||
return String.join(",", ouScopes);
|
||||
}
|
||||
|
||||
public static void closeContext(LdapContext ldapCtx) {
|
||||
private static void closeContext(LdapContext ldapCtx) {
|
||||
if (ldapCtx == null) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user