refactor(LDAP): 登录逻辑处理

This commit is contained in:
shiziyuan9527 2022-01-04 17:51:58 +08:00 committed by 刘瑞斌
parent 9dfded3197
commit 2e6e02130c
2 changed files with 58 additions and 66 deletions

View File

@ -1,89 +1,24 @@
package io.metersphere.ldap.controller; package io.metersphere.ldap.controller;
import io.metersphere.base.domain.User;
import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.exception.MSException;
import io.metersphere.controller.ResultHolder; import io.metersphere.controller.ResultHolder;
import io.metersphere.controller.request.LoginRequest; import io.metersphere.controller.request.LoginRequest;
import io.metersphere.i18n.Translator;
import io.metersphere.ldap.service.LdapService; import io.metersphere.ldap.service.LdapService;
import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.service.SystemParameterService;
import io.metersphere.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@RestController @RestController
@RequestMapping("/ldap") @RequestMapping("/ldap")
public class LdapController { public class LdapController {
@Resource
private UserService userService;
@Resource @Resource
private LdapService ldapService; private LdapService ldapService;
@Resource
private SystemParameterService systemParameterService;
@PostMapping(value = "/signin") @PostMapping(value = "/signin")
@MsAuditLog(module = "system_parameter_setting", type = OperLogConstants.LOGIN, title = "LDAP") @MsAuditLog(module = "system_parameter_setting", type = OperLogConstants.LOGIN, title = "LDAP")
public ResultHolder login(@RequestBody LoginRequest request) { public ResultHolder login(@RequestBody LoginRequest request) {
return ldapService.login(request);
String isOpen = systemParameterService.getValue(ParamConstants.LDAP.OPEN.getValue());
if (StringUtils.isBlank(isOpen) || StringUtils.equals(Boolean.FALSE.toString(), isOpen)) {
MSException.throwException(Translator.get("ldap_authentication_not_enabled"));
}
DirContextOperations dirContext = ldapService.authenticate(request);
String email = ldapService.getMappingAttr("email", dirContext);
String userId = ldapService.getMappingAttr("username", dirContext);
SecurityUtils.getSubject().getSession().setAttribute("authenticate", UserSource.LDAP.name());
SecurityUtils.getSubject().getSession().setAttribute("email", email);
if (StringUtils.isBlank(email)) {
MSException.throwException(Translator.get("login_fail_email_null"));
}
// userId email 有一个相同即为存在本地用户
User u = userService.selectUser(userId, email);
String name = ldapService.getMappingAttr("name", dirContext);
String phone = ldapService.getNotRequiredMappingAttr("phone", dirContext);
if (u == null) {
// 新建用户 获取LDAP映射属性
// String name = ldapService.getMappingAttr("name", dirContext);
// String phone = ldapService.getNotRequiredMappingAttr("phone", dirContext);
User user = new User();
user.setId(userId);
user.setName(name);
user.setEmail(email);
if (StringUtils.isNotBlank(phone)) {
user.setPhone(phone);
}
user.setSource(UserSource.LDAP.name());
userService.addLdapUser(user);
} else {
// 更新
u.setName(name);
u.setPhone(phone);
u.setEmail(email);
userService.updateUser(u);
}
// 执行 LocalRealm LDAP 登录逻辑
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUsername(userId);
return userService.login(loginRequest);
} }
@PostMapping("/test/connect") @PostMapping("/test/connect")

View File

@ -1,14 +1,19 @@
package io.metersphere.ldap.service; package io.metersphere.ldap.service;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import io.metersphere.base.domain.User;
import io.metersphere.commons.constants.ParamConstants; import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.EncryptUtils; import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.controller.ResultHolder;
import io.metersphere.controller.request.LoginRequest; import io.metersphere.controller.request.LoginRequest;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.service.SystemParameterService; import io.metersphere.service.SystemParameterService;
import io.metersphere.service.UserService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.realm.ldap.LdapUtils; import org.apache.shiro.realm.ldap.LdapUtils;
import org.springframework.ldap.AuthenticationException; import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.InvalidNameException; import org.springframework.ldap.InvalidNameException;
@ -38,6 +43,8 @@ public class LdapService {
@Resource @Resource
private SystemParameterService service; private SystemParameterService service;
@Resource
private UserService userService;
public DirContextOperations authenticate(LoginRequest request) { public DirContextOperations authenticate(LoginRequest request) {
String username = request.getUsername(); String username = request.getUsername();
@ -71,6 +78,56 @@ public class LdapService {
return authenticate(dn, credentials, ldapTemplate); return authenticate(dn, credentials, ldapTemplate);
} }
public ResultHolder login(LoginRequest request) {
String isOpen = service.getValue(ParamConstants.LDAP.OPEN.getValue());
if (StringUtils.isBlank(isOpen) || StringUtils.equals(Boolean.FALSE.toString(), isOpen)) {
MSException.throwException(Translator.get("ldap_authentication_not_enabled"));
}
DirContextOperations dirContext = authenticate(request);
String email = getMappingAttr("email", dirContext);
String userId = getMappingAttr("username", dirContext);
SecurityUtils.getSubject().getSession().setAttribute("authenticate", UserSource.LDAP.name());
SecurityUtils.getSubject().getSession().setAttribute("email", email);
if (StringUtils.isBlank(email)) {
MSException.throwException(Translator.get("login_fail_email_null"));
}
// userId email 有一个相同即为存在本地用户
User u = userService.selectUser(userId, email);
String name = getMappingAttr("name", dirContext);
String phone = getNotRequiredMappingAttr("phone", dirContext);
if (u == null) {
// 新建用户 获取LDAP映射属性
User user = new User();
user.setId(userId);
user.setName(name);
user.setEmail(email);
if (StringUtils.isNotBlank(phone)) {
user.setPhone(phone);
}
user.setSource(UserSource.LDAP.name());
userService.addLdapUser(user);
} else {
// 更新
u.setName(name);
u.setPhone(phone);
u.setEmail(email);
userService.updateUser(u);
}
// 执行 LocalRealm LDAP 登录逻辑
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUsername(userId);
return userService.login(loginRequest);
}
private boolean authenticate(String dn, String credentials, LdapTemplate ldapTemplate) throws AuthenticationException { private boolean authenticate(String dn, String credentials, LdapTemplate ldapTemplate) throws AuthenticationException {
DirContext ctx = null; DirContext ctx = null;
try { try {