optimize ldap

This commit is contained in:
zengqiao
2021-03-09 15:13:55 +08:00
parent fcb85ff4be
commit d5db028f57
4 changed files with 56 additions and 80 deletions

View File

@@ -0,0 +1,130 @@
package com.xiaojukeji.kafka.manager.account.component.ldap;
import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;
@Component
public class LdapAuthentication {
private static final Logger LOGGER = LoggerFactory.getLogger(LdapAuthentication.class);
@Value(value = "${account.ldap.url:}")
private String ldapUrl;
@Value(value = "${account.ldap.basedn:}")
private String ldapBasedn;
@Value(value = "${account.ldap.factory:}")
private String ldapFactory;
@Value(value = "${account.ldap.filter:}")
private String ldapFilter;
@Value(value = "${account.ldap.security.authentication:}")
private String securityAuthentication;
@Value(value = "${account.ldap.security.principal:}")
private String securityPrincipal;
@Value(value = "${account.ldap.security.credentials:}")
private String securityCredentials;
private LdapContext getLdapContext() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, ldapFactory);
env.put(Context.PROVIDER_URL, ldapUrl + ldapBasedn);
env.put(Context.SECURITY_AUTHENTICATION, securityAuthentication);
// 此处若不指定用户名和密码,则自动转换为匿名登录
env.put(Context.SECURITY_PRINCIPAL, securityPrincipal);
env.put(Context.SECURITY_CREDENTIALS, securityCredentials);
try {
return new InitialLdapContext(env, null);
} catch (AuthenticationException e) {
LOGGER.warn("class=LdapAuthentication||method=getLdapContext||errMsg={}", e);
} catch (Exception e) {
LOGGER.error("class=LdapAuthentication||method=getLdapContext||errMsg={}", e);
}
return null;
}
private String getUserDN(String account, LdapContext ctx) {
String userDN = "";
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(objectClass=*)("+ldapFilter+"=" + account + "))";
NamingEnumeration<SearchResult> en = ctx.search("", filter, constraints);
if (en == null || !en.hasMoreElements()) {
return "";
}
// maybe more than one element
while (en.hasMoreElements()) {
Object obj = en.nextElement();
if (obj instanceof SearchResult) {
SearchResult si = (SearchResult) obj;
userDN += si.getName();
userDN += "," + ldapBasedn;
break;
}
}
} catch (Exception e) {
LOGGER.error("class=LdapAuthentication||method=getUserDN||account={}||errMsg={}", account, e);
}
return userDN;
}
/**
* LDAP账密验证
* @param account
* @param password
* @return
*/
public boolean authenticate(String account, String password) {
LdapContext ctx = getLdapContext();
if (ValidateUtils.isNull(ctx)) {
return false;
}
try {
String userDN = getUserDN(account, ctx);
if(ValidateUtils.isBlank(userDN)){
return false;
}
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(null);
return true;
} catch (AuthenticationException e) {
LOGGER.warn("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e);
} catch (NamingException e) {
LOGGER.warn("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e);
} catch (Exception e) {
LOGGER.error("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e);
} finally {
if(ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
LOGGER.error("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e);
}
}
}
return false;
}
}

View File

@@ -2,7 +2,6 @@ package com.xiaojukeji.kafka.manager.account.component.sso;
import com.xiaojukeji.kafka.manager.account.AccountService;
import com.xiaojukeji.kafka.manager.account.component.AbstractSingleSignOn;
import com.xiaojukeji.kafka.manager.common.bizenum.AccountRoleEnum;
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
import com.xiaojukeji.kafka.manager.common.entity.Result;
import com.xiaojukeji.kafka.manager.common.entity.ResultStatus;
@@ -10,7 +9,7 @@ import com.xiaojukeji.kafka.manager.common.entity.dto.normal.LoginDTO;
import com.xiaojukeji.kafka.manager.common.entity.pojo.AccountDO;
import com.xiaojukeji.kafka.manager.common.utils.EncryptUtil;
import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils;
import com.xiaojukeji.kafka.manager.common.utils.ldap.LDAPAuthentication;
import com.xiaojukeji.kafka.manager.account.component.ldap.LdapAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -28,19 +27,11 @@ public class BaseSessionSignOn extends AbstractSingleSignOn {
private AccountService accountService;
@Autowired
private LDAPAuthentication ldapAuthentication;
private LdapAuthentication ldapAuthentication;
//是否开启ldap验证
@Value(value = "${ldap.enabled}")
private boolean ldapEnabled;
//ldap自动注册的默认角色。请注意它通常来说都是低权限角色
@Value(value = "${ldap.auth-user-registration-role}")
private String authUserRegistrationRole;
//ldap自动注册是否开启
@Value(value = "${ldap.auth-user-registration}")
private boolean authUserRegistration;
@Value(value = "${account.ldap.enabled:}")
private Boolean accountLdapEnabled;
@Override
public Result<String> loginAndGetLdap(HttpServletRequest request, HttpServletResponse response, LoginDTO dto) {
@@ -50,27 +41,15 @@ public class BaseSessionSignOn extends AbstractSingleSignOn {
Result<AccountDO> accountResult = accountService.getAccountDO(dto.getUsername());
//modifier limin
//判断是否激活了LDAP验证。若激活并且数据库无此用户则自动注册
if(ldapEnabled){
//判断是否激活了LDAP验证, 若激活则也可使用ldap进行认证
if(!ValidateUtils.isNull(accountLdapEnabled) && accountLdapEnabled){
//去LDAP验证账密
if(!ldapAuthentication.authenricate(dto.getUsername(),dto.getPassword())){
if(!ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword())){
return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED);
}
if((ValidateUtils.isNull(accountResult) || ValidateUtils.isNull(accountResult.getData())) && authUserRegistration){
//自动注册
AccountDO accountDO = new AccountDO();
accountDO.setUsername(dto.getUsername());
accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole());
accountDO.setPassword(EncryptUtil.md5(dto.getPassword()));
accountService.createAccount(accountDO);
}
return Result.buildSuc(dto.getUsername());
}
if (ValidateUtils.isNull(accountResult) || accountResult.failed()) {
return new Result<>(accountResult.getCode(), accountResult.getMessage());
}