Merge pull request #473 from didi/dev

Dev
This commit is contained in:
EricZeng
2022-03-07 14:49:52 +08:00
committed by GitHub
147 changed files with 1828 additions and 924 deletions

View File

@@ -54,7 +54,8 @@ public class BaseEnterpriseStaffService extends AbstractEnterpriseStaffService {
}
List<EnterpriseStaff> staffList = new ArrayList<>();
for (AccountDO accountDO: doList) {
staffList.add(new EnterpriseStaff(accountDO.getUsername(), accountDO.getUsername(), ""));
//这里对chineseName填充共识的displayNameDepartment则获取Department信息
staffList.add(new EnterpriseStaff(accountDO.getUsername(), accountDO.getDisplayName(), accountDO.getDepartment()));
}
return staffList;
} catch (Exception e) {

View File

@@ -1,5 +1,6 @@
package com.xiaojukeji.kafka.manager.account.component.ldap;
import com.xiaojukeji.kafka.manager.common.utils.SplitUtils;
import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,7 +15,9 @@ import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@Component
public class LdapAuthentication {
@@ -60,8 +63,11 @@ public class LdapAuthentication {
return null;
}
private String getUserDN(String account, LdapContext ctx) {
private Map<String, Object> getLdapAttrsInfo(String account, LdapContext ctx) {
//存储更多的LDAP元信息
Map<String, Object> ldapAttrsInfo = new HashMap<>();
String userDN = "";
ldapAttrsInfo.clear();
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
@@ -69,7 +75,7 @@ public class LdapAuthentication {
NamingEnumeration<SearchResult> en = ctx.search("", filter, constraints);
if (en == null || !en.hasMoreElements()) {
return "";
return null;
}
// maybe more than one element
while (en.hasMoreElements()) {
@@ -78,13 +84,25 @@ public class LdapAuthentication {
SearchResult si = (SearchResult) obj;
userDN += si.getName();
userDN += "," + ldapBasedn;
//携带LDAP更多元信息以填充用户元信息
ldapAttrsInfo.put("userDN", userDN);
ldapAttrsInfo.put("sAMAccountName",
SplitUtils.keyValueSplit(si.getAttributes().get("samaccountname").toString()));
ldapAttrsInfo.put("department",
SplitUtils.keyValueSplit(si.getAttributes().get("department").toString()));
ldapAttrsInfo.put("company",
SplitUtils.keyValueSplit(si.getAttributes().get("company").toString()));
ldapAttrsInfo.put("displayName",
SplitUtils.keyValueSplit(si.getAttributes().get("displayname").toString()));
ldapAttrsInfo.put("mail",
SplitUtils.keyValueSplit(si.getAttributes().get("mail").toString()));
break;
}
}
} catch (Exception e) {
LOGGER.error("class=LdapAuthentication||method=getUserDN||account={}||errMsg={}", account, e);
}
return userDN;
return ldapAttrsInfo;
}
/**
@@ -93,23 +111,23 @@ public class LdapAuthentication {
* @param password
* @return
*/
public boolean authenticate(String account, String password) {
public Map<String, Object> authenticate(String account, String password) {
LdapContext ctx = getLdapContext();
if (ValidateUtils.isNull(ctx)) {
return false;
return null;
}
try {
String userDN = getUserDN(account, ctx);
if(ValidateUtils.isBlank(userDN)){
return false;
Map<String, Object> ldapAttrsInfo = getLdapAttrsInfo(account, ctx);
if(ValidateUtils.isNull(ldapAttrsInfo)){
return null;
}
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, ldapAttrsInfo.get("userDN").toString());
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(null);
return true;
return ldapAttrsInfo;
} catch (AuthenticationException e) {
LOGGER.warn("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e);
} catch (NamingException e) {
@@ -125,6 +143,6 @@ public class LdapAuthentication {
}
}
}
return false;
return null;
}
}

View File

@@ -17,6 +17,7 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* @author zengqiao
@@ -31,43 +32,53 @@ public class BaseSessionSignOn extends AbstractSingleSignOn {
private LdapAuthentication ldapAuthentication;
//是否开启ldap验证
@Value(value = "${account.ldap.enabled:}")
@Value(value = "${account.ldap.enabled:false}")
private Boolean accountLdapEnabled;
//ldap自动注册的默认角色。请注意它通常来说都是低权限角色
@Value(value = "${account.ldap.auth-user-registration-role:}")
@Value(value = "${account.ldap.auth-user-registration-role:normal}")
private String authUserRegistrationRole;
//ldap自动注册是否开启
@Value(value = "${account.ldap.auth-user-registration:}")
private boolean authUserRegistration;
@Value(value = "${account.ldap.auth-user-registration:false}")
private Boolean authUserRegistration;
@Override
public Result<String> loginAndGetLdap(HttpServletRequest request, HttpServletResponse response, LoginDTO dto) {
if (ValidateUtils.isBlank(dto.getUsername()) || ValidateUtils.isNull(dto.getPassword())) {
return Result.buildFailure("Missing parameters");
}
Result<AccountDO> accountResult = accountService.getAccountDO(dto.getUsername());
//先创建空对象看是在LDAP去做填充还是直接查表填充
Result<AccountDO> accountResult;
//判断是否激活了LDAP验证, 若激活则也可使用ldap进行认证
if(!ValidateUtils.isNull(accountLdapEnabled) && accountLdapEnabled){
//去LDAP验证账密
if(!ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword())){
Map<String, Object> ldapAttrsInfo = ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword());;
if(ValidateUtils.isNull(ldapAttrsInfo)){
return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED);
}
//LDAP验证通过拿LDAP的sAMAccountName替换dto对象的值便于第一次自动注册采用LDAP值并且第二次也避免REPLACE
dto.setUsername(ldapAttrsInfo.get("sAMAccountName").toString());
accountResult = accountService.getAccountDO(dto.getUsername());
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(dto.getPassword());
accountDO.setDisplayName(ldapAttrsInfo.getOrDefault("displayName", "").toString());
accountDO.setDepartment(ldapAttrsInfo.getOrDefault("department", "").toString());
accountDO.setMail(ldapAttrsInfo.getOrDefault("mail", "").toString());
accountService.createAccount(accountDO);
}
return Result.buildSuc(dto.getUsername());
}
//不走LDAP认证直接查表填充
accountResult = accountService.getAccountDO(dto.getUsername());
if (ValidateUtils.isNull(accountResult) || accountResult.failed()) {
return new Result<>(accountResult.getCode(), accountResult.getMessage());

View File

@@ -275,6 +275,9 @@ public class AccountServiceImpl implements AccountService {
return enterpriseStaffService.searchEnterpriseStaffByKeyWord(prefix);
}
/**
* 定时刷新account信息到缓存中
*/
@Scheduled(cron ="0/5 * * * * ?")
public void flush() {
try {

View File

@@ -14,6 +14,7 @@ import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
@@ -27,7 +28,13 @@ import javax.servlet.http.HttpSession;
*/
@Service("loginService")
public class LoginServiceImpl implements LoginService {
private final static Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);
private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);
@Value(value = "${account.jump-login.gateway-api:false}")
private Boolean jumpLoginGatewayApi;
@Value(value = "${account.jump-login.third-part-api:false}")
private Boolean jumpLoginThirdPartApi;
@Autowired
private AccountService accountService;
@@ -75,8 +82,10 @@ public class LoginServiceImpl implements LoginService {
return false;
}
if (classRequestMappingValue.equals(ApiPrefix.API_V1_SSO_PREFIX)) {
// 白名单接口直接true
if (classRequestMappingValue.equals(ApiPrefix.API_V1_SSO_PREFIX) ||
(jumpLoginGatewayApi != null && jumpLoginGatewayApi && classRequestMappingValue.equals(ApiPrefix.GATEWAY_API_V1_PREFIX)) ||
(jumpLoginThirdPartApi != null && jumpLoginThirdPartApi && classRequestMappingValue.equals(ApiPrefix.API_V1_THIRD_PART_PREFIX))) {
// 登录接口 or 允许跳过且是跳过类型的接口,则直接跳过登录
return true;
}