新功能:增加对LDAP的登录的支持

This commit is contained in:
李民
2021-02-09 11:33:54 +08:00
parent b74612fa41
commit 25e84b2a6c
4 changed files with 175 additions and 2 deletions

View File

@@ -47,4 +47,13 @@ public enum AccountRoleEnum {
} }
return AccountRoleEnum.UNKNOWN; return AccountRoleEnum.UNKNOWN;
} }
public static AccountRoleEnum getUserRoleEnum(String roleName) {
for (AccountRoleEnum elem: AccountRoleEnum.values()) {
if (elem.message.equalsIgnoreCase(roleName)) {
return elem;
}
}
return AccountRoleEnum.UNKNOWN;
}
} }

View File

@@ -0,0 +1,112 @@
package com.xiaojukeji.kafka.manager.common.utils.ldap;
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 {
@Value(value = "${ldap.url}")
private String ldapUrl;
@Value(value = "${ldap.basedn}")
private String ldapBasedn;
@Value(value = "${ldap.factory}")
private String ldapFactory;
@Value(value = "${ldap.auth-user-registration-role}")
private String authUserRegistrationRole;
@Value(value = "${ldap.security.authentication}")
private String securityAuthentication;
@Value(value = "${ldap.security.principal}")
private String securityPrincipal;
@Value(value = "${ldap.security.credentials}")
private String securityCredentials;
private LdapContext getConnect() {
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) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getUserDN(String account) {
String userDN = null;
LdapContext ctx = getConnect();
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> en = ctx.search("", "account=" + account, constraints);
if (en == null || !en.hasMoreElements()) {
return null;
}
// 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) {
e.printStackTrace();
}
return userDN;
}
/**
* LDAP账密验证
* @param account
* @param password
* @return
*/
public boolean authenricate(String account, String password) {
LdapContext ctx = getConnect();
boolean valide = false;
String userDN = getUserDN(account);
try {
assert ctx != null;
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(null);
valide = true;
} catch (AuthenticationException e) {
System.out.println(e.toString());
} catch (NamingException e) {
e.printStackTrace();
}
return valide;
}
}

View File

@@ -2,12 +2,15 @@ package com.xiaojukeji.kafka.manager.account.component.sso;
import com.xiaojukeji.kafka.manager.account.AccountService; import com.xiaojukeji.kafka.manager.account.AccountService;
import com.xiaojukeji.kafka.manager.account.component.AbstractSingleSignOn; 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.constant.LoginConstant;
import com.xiaojukeji.kafka.manager.common.entity.dto.normal.LoginDTO; 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.entity.pojo.AccountDO;
import com.xiaojukeji.kafka.manager.common.utils.EncryptUtil; import com.xiaojukeji.kafka.manager.common.utils.EncryptUtil;
import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils;
import com.xiaojukeji.kafka.manager.common.utils.ldap.LDAPAuthentication;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -22,12 +25,49 @@ public class BaseSessionSignOn extends AbstractSingleSignOn {
@Autowired @Autowired
private AccountService accountService; private AccountService accountService;
@Autowired
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;
@Override @Override
public String loginAndGetLdap(HttpServletRequest request, HttpServletResponse response, LoginDTO dto) { public String loginAndGetLdap(HttpServletRequest request, HttpServletResponse response, LoginDTO dto) {
if (ValidateUtils.isBlank(dto.getUsername()) || ValidateUtils.isNull(dto.getPassword())) { if (ValidateUtils.isBlank(dto.getUsername()) || ValidateUtils.isNull(dto.getPassword())) {
return null; return null;
} }
AccountDO accountDO = accountService.getAccountDO(dto.getUsername()); AccountDO accountDO = accountService.getAccountDO(dto.getUsername());
//modifier limin
//判断是否激活了LDAP验证。若激活并且数据库无此用户则自动注册
if(ldapEnabled){
//验证账密
if(!ldapAuthentication.authenricate(dto.getUsername(),dto.getPassword())){
return null;
}
if(authUserRegistration){
//自动注册
accountDO = new AccountDO();
accountDO.setUsername(dto.getUsername());
accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole());
accountDO.setPassword(EncryptUtil.md5(dto.getPassword()));
accountService.createAccount(accountDO);
return dto.getUsername();
}
}
if (ValidateUtils.isNull(accountDO)) { if (ValidateUtils.isNull(accountDO)) {
return null; return null;
} }

View File

@@ -12,8 +12,8 @@ spring:
datasource: datasource:
kafka-manager: kafka-manager:
jdbc-url: jdbc:mysql://127.0.0.1:3306/logi_kafka_manager?characterEncoding=UTF-8&serverTimezone=GMT%2B8 jdbc-url: jdbc:mysql://127.0.0.1:3306/logi_kafka_manager?characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: admin username: root
password: admin password: root
driver-class-name: com.mysql.jdbc.Driver driver-class-name: com.mysql.jdbc.Driver
main: main:
allow-bean-definition-overriding: true allow-bean-definition-overriding: true
@@ -79,3 +79,15 @@ notify:
topic-name: didi-kafka-notify topic-name: didi-kafka-notify
order: order:
detail-url: http://127.0.0.1 detail-url: http://127.0.0.1
ldap:
enabled: false
url: ldap://127.0.0.1:389/
basedn: dc=tsign,dc=cn
factory: com.sun.jndi.ldap.LdapCtxFactory
security:
authentication: simple
principal: cn=admin,dc=tsign,dc=cn
credentials: admin
auth-user-registration-role: normal
auth-user-registration: true