diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index 7fa763b5f7b..57e2c263e6a 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -137,6 +137,7 @@ nacos.core.auth.plugin.nacos.token.secret.key=SecretKey0123456789012345678901234 #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org #nacos.core.auth.ldap.filter.prefix=uid +#nacos.core.auth.ldap.case.sensitive=true #*************** Istio Related Configurations ***************# diff --git a/distribution/conf/application.properties b/distribution/conf/application.properties index 4b5176c722b..574bc24e643 100644 --- a/distribution/conf/application.properties +++ b/distribution/conf/application.properties @@ -159,6 +159,7 @@ nacos.core.auth.plugin.nacos.token.secret.key=SecretKey0123456789012345678901234 #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org #nacos.core.auth.ldap.filter.prefix=uid +#nacos.core.auth.ldap.case.sensitive=true #*************** Istio Related Configurations ***************# diff --git a/distribution/conf/application.properties.example b/distribution/conf/application.properties.example index bb43880cb24..d294f9e97e4 100644 --- a/distribution/conf/application.properties.example +++ b/distribution/conf/application.properties.example @@ -147,6 +147,7 @@ nacos.core.auth.enabled=false #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org #nacos.core.auth.ldap.filter.prefix=uid +#nacos.core.auth.ldap.case.sensitive=true ### The token expiration in seconds: diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthConfig.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthConfig.java index d17a81dd772..a8e537a8e5b 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthConfig.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthConfig.java @@ -56,6 +56,9 @@ public class LdapAuthConfig { @Value(("${" + AuthConstants.NACOS_CORE_AUTH_LDAP_FILTER_PREFIX + ":uid}")) private String filterPrefix; + @Value(("${" + AuthConstants.NACOS_CORE_AUTH_CASE_SENSITIVE + ":true}")) + private boolean caseSensitive; + @Bean @Conditional(ConditionOnLdapAuth.class) public LdapTemplate ldapTemplate(LdapContextSource ldapContextSource) { @@ -71,7 +74,8 @@ public LdapContextSource ldapContextSource() { @Conditional(ConditionOnLdapAuth.class) public LdapAuthenticationProvider ldapAuthenticationProvider(LdapTemplate ldapTemplate, NacosUserDetailsServiceImpl userDetailsService, NacosRoleServiceImpl nacosRoleService) { - return new LdapAuthenticationProvider(ldapTemplate, userDetailsService, nacosRoleService, filterPrefix); + return new LdapAuthenticationProvider(ldapTemplate, userDetailsService, nacosRoleService, filterPrefix, + caseSensitive); } } diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProvider.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProvider.java index 34f5c5b33ef..d0c8857aa89 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProvider.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProvider.java @@ -25,6 +25,7 @@ import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetails; import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.plugin.auth.impl.utils.PasswordEncoderUtil; +import org.apache.commons.lang.StringUtils; import org.springframework.ldap.core.LdapTemplate; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -47,19 +48,22 @@ public class LdapAuthenticationProvider implements AuthenticationProvider { private static final String LDAP_PREFIX = "LDAP_"; private final NacosUserDetailsServiceImpl userDetailsService; - + private final NacosRoleServiceImpl nacosRoleService; - + private final LdapTemplate ldapTemplate; private final String filterPrefix; + private final boolean caseSensitive; + public LdapAuthenticationProvider(LdapTemplate ldapTemplate, NacosUserDetailsServiceImpl userDetailsService, - NacosRoleServiceImpl nacosRoleService, String filterPrefix) { + NacosRoleServiceImpl nacosRoleService, String filterPrefix, boolean caseSensitive) { this.ldapTemplate = ldapTemplate; this.nacosRoleService = nacosRoleService; this.userDetailsService = userDetailsService; this.filterPrefix = filterPrefix; + this.caseSensitive = caseSensitive; } @Override @@ -76,6 +80,10 @@ public Authentication authenticate(Authentication authentication) throws Authent } } + if (!caseSensitive) { + username = StringUtils.lowerCase(username); + } + try { if (!ldapLogin(username, password)) { return null; diff --git a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java index 5d1a859b8de..751edae2156 100644 --- a/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java +++ b/plugin-default-impl/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java @@ -62,4 +62,6 @@ public class AuthConstants { public static final String NACOS_CORE_AUTH_LDAP_PASSWORD = "nacos.core.auth.ldap.password"; public static final String NACOS_CORE_AUTH_LDAP_FILTER_PREFIX = "nacos.core.auth.ldap.filter.prefix"; + + public static final String NACOS_CORE_AUTH_CASE_SENSITIVE = "nacos.core.auth.ldap.case.sensitive"; } diff --git a/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java b/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java index 87d39c6e11a..8f38797a3d5 100644 --- a/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java +++ b/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java @@ -18,8 +18,11 @@ import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; import com.alibaba.nacos.plugin.auth.impl.persistence.RoleInfo; +import com.alibaba.nacos.plugin.auth.impl.persistence.User; import com.alibaba.nacos.plugin.auth.impl.roles.NacosRoleServiceImpl; +import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetails; import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl; +import org.apache.commons.lang.StringUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -29,6 +32,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.springframework.ldap.core.LdapTemplate; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -51,6 +56,8 @@ public class LdapAuthenticationProviderTest { private LdapAuthenticationProvider ldapAuthenticationProvider; + private LdapAuthenticationProvider ldapAuthenticationProviderForCloseCaseSensitive; + private List roleInfos = new ArrayList<>(); private final String adminUserName = "nacos"; @@ -59,6 +66,10 @@ public class LdapAuthenticationProviderTest { private final String filterPrefix = "uid"; + private final boolean caseSensitive = true; + + private static final String LDAP_PREFIX = "LDAP_"; + Method isAdmin; Method ldapLogin; @@ -73,8 +84,8 @@ public void setUp() throws NoSuchMethodException { roleInfos.add(adminRole); when(nacosRoleService.getRoles(adminUserName)).thenReturn(roleInfos); when(nacosRoleService.getRoles(normalUserName)).thenReturn(new ArrayList<>()); - when(ldapTemplate.authenticate("", "(" + filterPrefix + "=" + adminUserName + ")", defaultPassWord)).thenAnswer( - new Answer() { + when(ldapTemplate.authenticate("", "(" + filterPrefix + "=" + adminUserName + ")", defaultPassWord)) + .thenAnswer(new Answer() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); @@ -87,7 +98,9 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { } }); this.ldapAuthenticationProvider = new LdapAuthenticationProvider(ldapTemplate, userDetailsService, - nacosRoleService, filterPrefix); + nacosRoleService, filterPrefix, caseSensitive); + this.ldapAuthenticationProviderForCloseCaseSensitive = new LdapAuthenticationProvider(ldapTemplate, + userDetailsService, nacosRoleService, filterPrefix, !caseSensitive); isAdmin = LdapAuthenticationProvider.class.getDeclaredMethod("isAdmin", String.class); isAdmin.setAccessible(true); ldapLogin = LdapAuthenticationProvider.class.getDeclaredMethod("ldapLogin", String.class, String.class); @@ -134,4 +147,58 @@ public void testldapLogin() { Assert.fail(); } } + + @Test + public void testDefaultCaseSensitive() { + String userName = StringUtils.upperCase(normalUserName); + when(ldapTemplate.authenticate("", "(" + filterPrefix + "=" + userName + ")", defaultPassWord)) + .thenAnswer(new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + String b = (String) args[1]; + String c = (String) args[2]; + if (defaultPassWord.equals(c)) { + return true; + } + return false; + } + }); + User userUpperCase = new User(); + userUpperCase.setUsername(LDAP_PREFIX + userName); + userUpperCase.setPassword(defaultPassWord); + when(userDetailsService.loadUserByUsername(LDAP_PREFIX + userName)) + .thenReturn(new NacosUserDetails(userUpperCase)); + Authentication authentication = new UsernamePasswordAuthenticationToken(userName, defaultPassWord); + Authentication result = ldapAuthenticationProvider.authenticate(authentication); + NacosUserDetails nacosUserDetails = (NacosUserDetails) result.getPrincipal(); + Assert.assertTrue(nacosUserDetails.getUsername().equals(LDAP_PREFIX + userName)); + } + + @Test + public void testCloseCaseSensitive() { + when(ldapTemplate.authenticate("", "(" + filterPrefix + "=" + normalUserName + ")", defaultPassWord)) + .thenAnswer(new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + String b = (String) args[1]; + String c = (String) args[2]; + if (defaultPassWord.equals(c)) { + return true; + } + return false; + } + }); + User user = new User(); + user.setUsername(LDAP_PREFIX + normalUserName); + user.setPassword(defaultPassWord); + when(userDetailsService.loadUserByUsername(LDAP_PREFIX + normalUserName)) + .thenReturn(new NacosUserDetails(user)); + Authentication authentication = new UsernamePasswordAuthenticationToken(StringUtils.upperCase(normalUserName), + defaultPassWord); + Authentication result = ldapAuthenticationProviderForCloseCaseSensitive.authenticate(authentication); + NacosUserDetails nacosUserDetails = (NacosUserDetails) result.getPrincipal(); + Assert.assertTrue(nacosUserDetails.getUsername().equals(LDAP_PREFIX + normalUserName)); + } }