/*
* Copyright 2002-2016 the original author or authors.
*
* 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 org.springframework.security.config.ldap;
import java.util.Set;
import org.junit.After;
import org.junit.Test;
import org.w3c.dom.Element;
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
import org.springframework.security.ldap.userdetails.InetOrgPerson;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
import org.springframework.security.ldap.userdetails.LdapUserDetailsService;
import org.springframework.security.ldap.userdetails.Person;
import org.springframework.security.ldap.userdetails.PersonContextMapper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.INET_ORG_PERSON_MAPPER_CLASS;
import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.LDAP_AUTHORITIES_POPULATOR_CLASS;
import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.LDAP_SEARCH_CLASS;
import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.LDAP_USER_MAPPER_CLASS;
import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.PERSON_MAPPER_CLASS;
/**
* @author Luke Taylor
* @author Rob Winch
* @author EddĂș MelĂ©ndez
*/
public class LdapUserServiceBeanDefinitionParserTests {
private InMemoryXmlApplicationContext appCtx;
@After
public void closeAppContext() {
if (appCtx != null) {
appCtx.close();
appCtx = null;
}
}
@Test
public void beanClassNamesAreCorrect() throws Exception {
assertThat(FilterBasedLdapUserSearch.class.getName()).isEqualTo(LDAP_SEARCH_CLASS);
assertThat(PersonContextMapper.class.getName()).isEqualTo(PERSON_MAPPER_CLASS);
assertThat(InetOrgPersonContextMapper.class.getName()).isEqualTo(INET_ORG_PERSON_MAPPER_CLASS);
assertThat(LdapUserDetailsMapper.class.getName()).isEqualTo(LDAP_USER_MAPPER_CLASS);
assertThat(DefaultLdapAuthoritiesPopulator.class.getName()).isEqualTo(LDAP_AUTHORITIES_POPULATOR_CLASS);
assertThat(new LdapUserServiceBeanDefinitionParser().getBeanClassName(mock(Element.class))).isEqualTo(LdapUserDetailsService.class.getName());
}
@Test
public void minimalConfigurationIsParsedOk() throws Exception {
setContext("<ldap-user-service user-search-filter='(uid={0})' /><ldap-server ldif='classpath:test-server.ldif' url='ldap://127.0.0.1:343/dc=springframework,dc=org' />");
}
@Test
public void userServiceReturnsExpectedData() throws Exception {
setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
Set<String> authorities = AuthorityUtils.authorityListToSet(ben.getAuthorities());
assertThat(authorities).hasSize(3);
assertThat(authorities.contains("ROLE_DEVELOPERS")).isTrue();
}
@Test
public void differentUserSearchBaseWorksAsExpected() throws Exception {
setContext("<ldap-user-service id='ldapUDS' "
+ " user-search-base='ou=otherpeople' "
+ " user-search-filter='(cn={0})' "
+ " group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails joe = uds.loadUserByUsername("Joe Smeth");
assertThat(joe.getUsername()).isEqualTo("Joe Smeth");
}
@Test
public void rolePrefixIsSupported() throws Exception {
setContext("<ldap-user-service id='ldapUDS' "
+ " user-search-filter='(uid={0})' "
+ " group-search-filter='member={0}' role-prefix='PREFIX_'/>"
+ "<ldap-user-service id='ldapUDSNoPrefix' "
+ " user-search-filter='(uid={0})' "
+ " group-search-filter='member={0}' role-prefix='none'/><ldap-server ldif='classpath:test-server.ldif'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
assertThat(AuthorityUtils.authorityListToSet(ben.getAuthorities())).contains("PREFIX_DEVELOPERS");
uds = (UserDetailsService) appCtx.getBean("ldapUDSNoPrefix");
ben = uds.loadUserByUsername("ben");
assertThat(AuthorityUtils.authorityListToSet(ben.getAuthorities())).contains("DEVELOPERS");
}
@Test
public void differentGroupRoleAttributeWorksAsExpected() throws Exception {
setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
Set<String> authorities = AuthorityUtils.authorityListToSet(ben.getAuthorities());
assertThat(authorities).hasSize(3);
assertThat(authorities.contains("ROLE_DEVELOPER")).isTrue();
}
@Test
public void isSupportedByAuthenticationProviderElement() {
setContext("<ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org' ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <authentication-provider>"
+ " <ldap-user-service user-search-filter='(uid={0})' />"
+ " </authentication-provider>" + "</authentication-manager>");
}
@Test
public void personContextMapperIsSupported() {
setContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='person'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
assertThat(ben instanceof Person).isTrue();
}
@Test
public void inetOrgContextMapperIsSupported() {
setContext("<ldap-server id='someServer' ldif='classpath:test-server.ldif'/>"
+ "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='inetOrgPerson'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
assertThat(ben instanceof InetOrgPerson).isTrue();
}
@Test
public void externalContextMapperIsSupported() {
setContext("<ldap-server id='someServer' ldif='classpath:test-server.ldif'/>"
+ "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-context-mapper-ref='mapper'/>"
+ "<b:bean id='mapper' class='"
+ InetOrgPersonContextMapper.class.getName() + "'/>");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
assertThat(ben instanceof InetOrgPerson).isTrue();
}
private void setContext(String context) {
appCtx = new InMemoryXmlApplicationContext(context);
}
}