From 8d75c281510c84516cf78a0d12de480b5f3b6f1f Mon Sep 17 00:00:00 2001 From: karsonto Date: Tue, 20 Sep 2022 11:56:44 +0800 Subject: [PATCH 1/2] resolve issue #9175 add ldap filter config --- console/src/main/resources/application.properties | 1 + distribution/conf/application.properties | 1 + .../com/alibaba/nacos/plugin/auth/impl/LdapAuthConfig.java | 7 +++++-- .../nacos/plugin/auth/impl/LdapAuthenticationProvider.java | 7 +++++-- .../nacos/plugin/auth/impl/constant/AuthConstants.java | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index b39c4bde6df..21e77145d7b 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -145,6 +145,7 @@ nacos.core.auth.plugin.nacos.token.secret.key=SecretKey0123456789012345678901234 #nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc} #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org +#nacos.core.auth.ldap.filter.prefix=uid #*************** Istio Related Configurations ***************# diff --git a/distribution/conf/application.properties b/distribution/conf/application.properties index dd5e45567ca..7d55ef99a07 100644 --- a/distribution/conf/application.properties +++ b/distribution/conf/application.properties @@ -171,6 +171,7 @@ nacos.core.auth.plugin.nacos.token.secret.key=SecretKey0123456789012345678901234 #nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc} #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org +#nacos.core.auth.ldap.filter.prefix=uid #*************** Istio Related Configurations ***************# 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 89440b03eec..14cae9713ef 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 @@ -55,6 +55,9 @@ public class LdapAuthConfig { @Value(("${" + AuthConstants.NACOS_CORE_AUTH_LDAP_PASSWORD + ":password}")) private String password; + @Value(("${" + AuthConstants.NACOS_CORE_AUTH_LDAP_FILTER_PREFIX + ":uid}")) + private String filterPrefix; + @Bean @Conditional(ConditionOnLdapAuth.class) public LdapTemplate ldapTemplate() { @@ -76,8 +79,8 @@ public LdapTemplate ldapTemplate() { @Bean @Conditional(ConditionOnLdapAuth.class) public LdapAuthenticationProvider ldapAuthenticationProvider(LdapTemplate ldapTemplate, - NacosUserDetailsServiceImpl userDetailsService, NacosRoleServiceImpl nacosRoleService) { - return new LdapAuthenticationProvider(ldapTemplate, userDetailsService, nacosRoleService); + NacosUserDetailsServiceImpl userDetailsService, NacosRoleServiceImpl nacosRoleService, String filterPrefix) { + return new LdapAuthenticationProvider(ldapTemplate, userDetailsService, nacosRoleService, filterPrefix); } } 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 a212e598d19..34f5c5b33ef 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 @@ -52,11 +52,14 @@ public class LdapAuthenticationProvider implements AuthenticationProvider { private final LdapTemplate ldapTemplate; + private final String filterPrefix; + public LdapAuthenticationProvider(LdapTemplate ldapTemplate, NacosUserDetailsServiceImpl userDetailsService, - NacosRoleServiceImpl nacosRoleService) { + NacosRoleServiceImpl nacosRoleService, String filterPrefix) { this.ldapTemplate = ldapTemplate; this.nacosRoleService = nacosRoleService; this.userDetailsService = userDetailsService; + this.filterPrefix = filterPrefix; } @Override @@ -110,7 +113,7 @@ private boolean isAdmin(String username) { } private boolean ldapLogin(String username, String password) throws AuthenticationException { - return ldapTemplate.authenticate("", "(uid=" + username + ")", password); + return ldapTemplate.authenticate("", "(" + filterPrefix + "=" + username + ")", password); } @Override 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 cb2239a6275..33ca6d0ce77 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 @@ -60,4 +60,6 @@ public class AuthConstants { public static final String NACOS_CORE_AUTH_LDAP_USERDN = "nacos.core.auth.ldap.userDn"; 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"; } From f27113b3b0a5fcad63ec568c4ac647cf04b44bb5 Mon Sep 17 00:00:00 2001 From: karsonto Date: Tue, 20 Sep 2022 15:37:35 +0800 Subject: [PATCH 2/2] add some unit test --- .../conf/application.properties.example | 1 + .../impl/LdapAuthenticationProviderTest.java | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java diff --git a/distribution/conf/application.properties.example b/distribution/conf/application.properties.example index 403e21e986e..2e3d657391e 100644 --- a/distribution/conf/application.properties.example +++ b/distribution/conf/application.properties.example @@ -155,6 +155,7 @@ nacos.core.auth.enabled=false #nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc} #nacos.core.auth.ldap.password=admin #nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org +#nacos.core.auth.ldap.filter.prefix=uid ### The token expiration in seconds: 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 new file mode 100644 index 00000000000..87d39c6e11a --- /dev/null +++ b/plugin-default-impl/src/test/java/com/alibaba/nacos/plugin/auth/impl/LdapAuthenticationProviderTest.java @@ -0,0 +1,137 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.auth.impl; + +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.roles.NacosRoleServiceImpl; +import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; +import org.springframework.ldap.core.LdapTemplate; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class LdapAuthenticationProviderTest { + + @Mock + private NacosUserDetailsServiceImpl userDetailsService; + + @Mock + private NacosRoleServiceImpl nacosRoleService; + + @Mock + private LdapTemplate ldapTemplate; + + private LdapAuthenticationProvider ldapAuthenticationProvider; + + private List roleInfos = new ArrayList<>(); + + private final String adminUserName = "nacos"; + + private final String normalUserName = "normal"; + + private final String filterPrefix = "uid"; + + Method isAdmin; + + Method ldapLogin; + + private String defaultPassWord = "nacos"; + + @Before + public void setUp() throws NoSuchMethodException { + RoleInfo adminRole = new RoleInfo(); + adminRole.setRole(AuthConstants.GLOBAL_ADMIN_ROLE); + adminRole.setUsername(adminUserName); + 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() { + @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; + } + }); + this.ldapAuthenticationProvider = new LdapAuthenticationProvider(ldapTemplate, userDetailsService, + nacosRoleService, filterPrefix); + isAdmin = LdapAuthenticationProvider.class.getDeclaredMethod("isAdmin", String.class); + isAdmin.setAccessible(true); + ldapLogin = LdapAuthenticationProvider.class.getDeclaredMethod("ldapLogin", String.class, String.class); + ldapLogin.setAccessible(true); + } + + @Test + public void testIsAdmin() { + try { + Boolean result = (Boolean) isAdmin.invoke(ldapAuthenticationProvider, adminUserName); + Assert.assertTrue(result); + } catch (IllegalAccessException e) { + Assert.fail(); + } catch (InvocationTargetException e) { + Assert.fail(); + } + try { + Boolean result = (Boolean) isAdmin.invoke(ldapAuthenticationProvider, normalUserName); + Assert.assertTrue(!result); + } catch (IllegalAccessException e) { + Assert.fail(); + } catch (InvocationTargetException e) { + Assert.fail(); + } + + } + + @Test + public void testldapLogin() { + try { + Boolean result = (Boolean) ldapLogin.invoke(ldapAuthenticationProvider, adminUserName, defaultPassWord); + Assert.assertTrue(result); + } catch (IllegalAccessException e) { + Assert.fail(); + } catch (InvocationTargetException e) { + Assert.fail(); + } + try { + Boolean result = (Boolean) ldapLogin.invoke(ldapAuthenticationProvider, adminUserName, "123"); + Assert.assertTrue(!result); + } catch (IllegalAccessException e) { + Assert.fail(); + } catch (InvocationTargetException e) { + Assert.fail(); + } + } +}