Skip to content

Commit b43b4d5

Browse files
author
Chen, Taiyue
committed
<feature>[ldap]: refactor LDAP login logic and add two-factor authentication support
1. Extract common method findAccountThirdPartyAccountSourceRefByName - Extract the logic of finding third-party account source reference from login method into a standalone method - Unify account lookup logic in both login and collectUserInfoIntoContext methods 2. Add two-factor authentication support - getRequiredAdditionalAuthFeature method now returns a list containing both basicLoginControl and twoFactor - Support two-factor authentication for LDAP login Resolves: ZSV-11833 Change-Id: I7578626465676e6569686a786271786b64667179
1 parent 1340bd2 commit b43b4d5

5 files changed

Lines changed: 52 additions & 45 deletions

File tree

plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.zstack.core.Platform;
44
import org.zstack.header.errorcode.ErrorableValue;
5+
import org.zstack.identity.imports.entity.AccountThirdPartyAccountSourceRefVO;
56
import org.zstack.ldap.driver.LdapUtil;
67
import org.zstack.ldap.entity.LdapServerVO;
78

@@ -10,7 +11,7 @@
1011
*/
1112
public interface LdapManager {
1213
boolean isValid(String uid, String password);
13-
14+
ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword);
1415
ErrorableValue<String> findCurrentLdapServerUuid();
1516
ErrorableValue<LdapServerVO> findCurrentLdapServer();
1617

plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -407,44 +407,49 @@ public LoginType getLoginType() {
407407
return loginType;
408408
}
409409

410-
@Override
411-
public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
410+
public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword) {
412411
final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
413412
if (!currentLdapServer.isSuccess()) {
414-
logger.debug("failed to login by LDAP: failed to find current LdapServer: " + currentLdapServer.error.getDetails());
415-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
416-
"Login validation failed in LDAP"));
417-
return;
413+
return ErrorableValue.ofErrorCode(currentLdapServer.error);
418414
}
419415
final LdapServerVO ldap = currentLdapServer.result;
420416

421-
String ldapLoginName = loginContext.getUsername();
422-
if (!isValid(ldapLoginName, loginContext.getPassword())) {
423-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
424-
"Login validation failed in LDAP"));
425-
return;
426-
}
427-
428417
String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
429418
AccountThirdPartyAccountSourceRefVO vo = Q.New(AccountThirdPartyAccountSourceRefVO.class)
430419
.eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
431420
.eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
432421
.find();
433422

434423
if (vo == null) {
435-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
424+
return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
436425
"The ldapUid does not have a binding account."));
426+
}
427+
return ErrorableValue.of(vo);
428+
}
429+
430+
@Override
431+
public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
432+
final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
433+
434+
if (!accountThirdPartyAccountSourceRef.isSuccess()) {
435+
completion.fail(accountThirdPartyAccountSourceRef.error);
437436
return;
438437
}
439438

439+
if (!isValid(loginContext.getUsername(), loginContext.getPassword())) {
440+
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
441+
"Login validation failed in LDAP"));
442+
return;
443+
}
444+
String accountUuid = accountThirdPartyAccountSourceRef.result.getAccountUuid();
440445
final AccountState state = Q.New(AccountVO.class)
441-
.eq(AccountVO_.uuid, vo.getAccountUuid())
446+
.eq(AccountVO_.uuid, accountUuid)
442447
.select(AccountVO_.state)
443448
.findValue();
444449

445450
if (state == null || state == AccountState.Staled) {
446451
completion.fail(operr(
447-
"Account[uuid:%s] Not Found!!!", vo.getAccountUuid()));
452+
"Account[uuid:%s] Not Found!!!", accountUuid));
448453
return;
449454
}
450455
if (state == AccountState.Disabled) {
@@ -453,7 +458,7 @@ public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionI
453458
}
454459

455460
LoginSessionInfo info = new LoginSessionInfo();
456-
info.setAccountUuid(vo.getAccountUuid());
461+
info.setAccountUuid(accountUuid);
457462
completion.success(info);
458463
}
459464

@@ -468,21 +473,36 @@ public boolean authenticate(String username, String password) {
468473

469474
@Override
470475
public String getAccountIdByName(String username) {
471-
final ErrorableValue<LdapServerVO> property = findCurrentLdapServer();
472-
if (property.isSuccess()) {
473-
final String fullUserDn = createDriver().getFullUserDn(property.result, username);
474-
return "".equals(fullUserDn) ? null : fullUserDn;
476+
final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
477+
if (!currentLdapServer.isSuccess()) {
478+
return null;
479+
}
480+
final LdapServerVO ldap = currentLdapServer.result;
481+
482+
String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), username);
483+
if (dn == null || dn.isEmpty()) {
484+
return null;
475485
}
476-
return null;
486+
487+
String accountUuid = Q.New(AccountThirdPartyAccountSourceRefVO.class)
488+
.select(AccountThirdPartyAccountSourceRefVO_.accountUuid)
489+
.eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
490+
.eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
491+
.findValue();
492+
return accountUuid;
477493
}
478494

479495
@Override
480496
public void collectUserInfoIntoContext(LoginContext loginContext) {
481-
loginContext.setAccountUuid(getAccountIdByName(loginContext.getUsername()));
497+
ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
498+
if (!accountThirdPartyAccountSourceRef.isSuccess()) {
499+
return;
500+
}
501+
loginContext.setAccountUuid(accountThirdPartyAccountSourceRef.result.getAccountUuid());
482502
}
483503

484504
@Override
485505
public List<AdditionalAuthFeature> getRequiredAdditionalAuthFeature() {
486-
return Collections.singletonList(LoginAuthConstant.basicLoginControl);
506+
return Arrays.asList(LoginAuthConstant.basicLoginControl, LoginAuthConstant.twoFactor);
487507
}
488508
}

sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public Result throwExceptionIfError() {
3737
@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
3838
public java.lang.String verifyCode;
3939

40+
@Param(required = true, validValues = {"account","ldap"}, nonempty = true, nullElements = false, emptyString = true, noTrim = false)
41+
public java.lang.String type;
42+
4043
@Param(required = false)
4144
public java.util.List systemTags;
4245

sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public Result throwExceptionIfError() {
3737
@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
3838
public java.lang.String verifyCode;
3939

40+
@Param(required = true, validValues = {"account","ldap"}, nonempty = true, nullElements = false, emptyString = true, noTrim = false)
41+
public java.lang.String type;
42+
4043
@Param(required = false)
4144
public java.util.List systemTags;
4245

test/src/test/resources/springConfigXml/license.xml

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)