LDAP 测试连接

This commit is contained in:
shiziyuan9527 2020-07-01 18:38:48 +08:00
parent 404bbe395c
commit 62f6dd634c
6 changed files with 90 additions and 53 deletions

View File

@ -3,15 +3,13 @@ package io.metersphere.ldap.controller;
import io.metersphere.base.domain.User;
import io.metersphere.controller.ResultHolder;
import io.metersphere.controller.request.LoginRequest;
import io.metersphere.ldap.LdapService;
import io.metersphere.ldap.service.LdapService;
import io.metersphere.ldap.domain.LdapInfo;
import io.metersphere.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import static io.metersphere.commons.constants.SessionConstants.ATTR_USER;
@RestController
@RequestMapping("/ldap")
public class LdapController {
@ -47,8 +45,9 @@ public class LdapController {
return userService.login(request);
}
@PostMapping("/connect")
public void testConnect(@RequestBody LdapInfo ldapInfo) {
ldapService.testConnect(ldapInfo);
}
}

View File

@ -1,12 +1,10 @@
package io.metersphere.ldap;
package io.metersphere.ldap.dao;
import java.util.List;
public interface PersonRepo {
List<String> getAllPersonNames();
List findByName(String name);
String getDnForUser(String name);

View File

@ -1,45 +1,36 @@
package io.metersphere.ldap;
package io.metersphere.ldap.dao;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.ldap.domain.Person;
import io.metersphere.service.SystemParameterService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.realm.ldap.LdapUtils;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.*;
import org.springframework.ldap.core.support.AbstractContextMapper;
import org.springframework.ldap.core.support.DefaultDirObjectFactory;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
import java.util.List;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
@Service
public class PersonRepoImpl implements PersonRepo {
@Resource
private LdapTemplate ldapTemplate;
@Override
public List<String> getAllPersonNames() {
ldapTemplate.setIgnorePartialResultException(true);
return ldapTemplate.search(
query().where("objectclass").is("person"),
new AttributesMapper<String>() {
@Override
public String mapFromAttributes(Attributes attrs)
throws NamingException, javax.naming.NamingException {
return attrs.toString();
}
});
}
private SystemParameterService service;
public boolean authenticate(String dn, String credentials) {
LdapTemplate ldapTemplate = getConnection();
DirContext ctx = null;
try {
ctx = ldapTemplate.getContextSource().getContext(dn, credentials);
@ -57,7 +48,7 @@ public class PersonRepoImpl implements PersonRepo {
// Context creation failed - authentication did not succeed
LogUtil.error("ldap authenticate failed..." + e);
System.out.println("Login failed: " + e);
MSException.throwException("login failed...");
MSException.throwException("连接失败");
return false;
} finally {
// It is imperative that the created DirContext instance is always closed
@ -65,24 +56,18 @@ public class PersonRepoImpl implements PersonRepo {
}
}
public List<Person> getAllPersons() {
ldapTemplate.setIgnorePartialResultException(true);
return ldapTemplate.search(query()
.where("objectclass").is("person"), getContextMapper());
}
@Override
public List findByName(String name) {
LdapTemplate ldapTemplate = getConnection();
ldapTemplate.setIgnorePartialResultException(true);
LdapQuery query = query()
// .where("objectclass").is("person")
// .and("cn").is(name);
.where("cn").is(name);
LdapQuery query = query().where("cn").is(name);
return ldapTemplate.search(query, getContextMapper());
}
@Override
public String getDnForUser(String uid) {
LdapTemplate ldapTemplate = getConnection();
ldapTemplate.setIgnorePartialResultException(true);
List<String> result = ldapTemplate.search(
query().where("cn").is(uid),
new AbstractContextMapper() {
@ -92,7 +77,7 @@ public class PersonRepoImpl implements PersonRepo {
}
});
if(result.size() != 1) {
if (result.size() != 1) {
throw new RuntimeException("User not found or not unique");
}
@ -103,7 +88,6 @@ public class PersonRepoImpl implements PersonRepo {
return new PersonContextMapper();
}
private static class PersonContextMapper extends AbstractContextMapper<Person> {
@Override
public Person doMapFromContext(DirContextOperations context) {
@ -116,4 +100,44 @@ public class PersonRepoImpl implements PersonRepo {
}
}
public LdapTemplate getConnection() {
String url = service.getValue(ParamConstants.LDAP.URL.getValue());
String dn = service.getValue(ParamConstants.LDAP.DN.getValue());
String ou = service.getValue(ParamConstants.LDAP.OU.getValue());
String credentials = EncryptUtils.aesDecrypt(service.getValue(ParamConstants.LDAP.PASSWORD.getValue())).toString();
preConnect(url, dn, ou, credentials);
LdapContextSource sourceLdapCtx = new LdapContextSource();
sourceLdapCtx.setUrl(url);
sourceLdapCtx.setUserDn(dn);
sourceLdapCtx.setPassword(credentials);
sourceLdapCtx.setBase(ou);
sourceLdapCtx.setDirObjectFactory(DefaultDirObjectFactory.class);
sourceLdapCtx.afterPropertiesSet();
return new LdapTemplate(sourceLdapCtx);
}
private void preConnect(String url, String dn, String ou, String password) {
if (StringUtils.isBlank(url)) {
MSException.throwException("ldap url is null");
}
if (StringUtils.isBlank(dn)) {
MSException.throwException("ldap dn is null");
}
if (StringUtils.isBlank(ou)) {
MSException.throwException("ldap ou is null");
}
if (StringUtils.isBlank(password)) {
MSException.throwException("ldap password is null");
}
}
}

View File

@ -1,10 +1,13 @@
package io.metersphere.ldap;
package io.metersphere.ldap.service;
import io.metersphere.commons.exception.MSException;
import io.metersphere.controller.request.LoginRequest;
import io.metersphere.i18n.Translator;
import io.metersphere.ldap.dao.PersonRepoImpl;
import io.metersphere.ldap.domain.LdapInfo;
import org.springframework.ldap.CommunicationException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@ -14,7 +17,8 @@ public class LdapService {
@Resource
private PersonRepoImpl personRepo;
public boolean authenticate(LoginRequest request) {
public void authenticate(LoginRequest request) {
String dn = null;
String username = request.getUsername();
String credentials = request.getPassword();
@ -25,7 +29,7 @@ public class LdapService {
if (user.size() == 1) {
dn = personRepo.getDnForUser(username);
} else if (user.size() == 0){
} else if (user.size() == 0) {
MSException.throwException(Translator.get("user_not_exist") + username);
} else {
MSException.throwException("Found multiple users");
@ -33,7 +37,11 @@ public class LdapService {
} catch (CommunicationException e) {
MSException.throwException("LDAP Server connection failed!");
}
return personRepo.authenticate(dn, credentials);
personRepo.authenticate(dn, credentials);
}
public void testConnect(LdapInfo ldap) {
personRepo.authenticate(ldap.getDn(), ldap.getPassword());
}
}

View File

@ -7,7 +7,6 @@ import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.i18n.Translator;
import io.metersphere.ldap.LdapService;
import io.metersphere.ldap.domain.LdapInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
@ -156,4 +155,12 @@ public class SystemParameterService {
}
return ldap;
}
public String getValue(String key) {
SystemParameter param = systemParameterMapper.selectByPrimaryKey(key);
if (param == null) {
return null;
}
return param.getParamValue();
}
}

View File

@ -11,7 +11,7 @@
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码" show-password auto-complete="new-password"></el-input>
</el-form-item>
<el-form-item label="用户OU" porp="ou">
<el-form-item label="用户OU" prop="ou">
<el-input v-model="form.ou" placeholder="输入用户OU (使用|分隔各OU)"></el-input>
</el-form-item>
<el-form-item label="用户过滤器" prop="filter">
@ -52,7 +52,8 @@
rules: {
url: {required: true, message: '请输入LDAP地址', trigger: ['change']},
dn: {required: true, message: '请输入DN', trigger: ['change']},
password: {required: true, message: '请输入密码', trigger: ['change']}
password: {required: true, message: '请输入密码', trigger: ['change']},
ou: {required: true, message: '请输入OU', trigger: ['change']},
}
}
},
@ -61,7 +62,7 @@
},
methods: {
init() {
this.$get("/system/ldap/info", response => {
this.result = this.$get("/system/ldap/info", response => {
this.form = response.data;
this.form.open = this.form.open === 'true' ? true : false;
})
@ -80,8 +81,8 @@
this.init();
},
testConnection() {
this.$post("/system/test-connection/ldap", this.params, response => {
console.log(response)
this.result = this.$post("/ldap/connect", this.form, response => {
this.$success("连接成功!")
})
},
save(form) {