/* * 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.authentication; import org.junit.After; import org.junit.Test; import org.w3c.dom.Element; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication .UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.BeanIds; 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.provisioning.JdbcUserDetailsManager; import org.springframework.security.util.FieldUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** * @author Ben Alex * @author Luke Taylor * @author EddĂș MelĂ©ndez */ public class JdbcUserServiceBeanDefinitionParserTests { private static String USER_CACHE_XML = "<b:bean id='userCache' class='org.springframework.security.authentication.dao.MockUserCache'/>"; private static String DATA_SOURCE = " <b:bean id='populator' class='org.springframework.security.config.DataSourcePopulator'>" + " <b:property name='dataSource' ref='dataSource'/>" + " </b:bean>" + " <b:bean id='dataSource' class='org.springframework.security.TestDataSource'>" + " <b:constructor-arg value='jdbcnamespaces'/>" + " </b:bean>"; private InMemoryXmlApplicationContext appContext; @After public void closeAppContext() { if (appContext != null) { appContext.close(); } } @Test public void beanNameIsCorrect() throws Exception { assertThat(JdbcUserDetailsManager.class.getName()).isEqualTo( new JdbcUserServiceBeanDefinitionParser() .getBeanClassName(mock(Element.class))); } @Test public void validUsernameIsFound() { setContext("<jdbc-user-service data-source-ref='dataSource'/>" + DATA_SOURCE); JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext .getBean(BeanIds.USER_DETAILS_SERVICE); assertThat(mgr.loadUserByUsername("rod")).isNotNull(); } @Test public void beanIdIsParsedCorrectly() { setContext("<jdbc-user-service id='myUserService' data-source-ref='dataSource'/>" + DATA_SOURCE); assertThat(appContext.getBean("myUserService") instanceof JdbcUserDetailsManager).isTrue(); } @Test public void usernameAndAuthorityQueriesAreParsedCorrectly() throws Exception { String userQuery = "select username, password, true from users where username = ?"; String authoritiesQuery = "select username, authority from authorities where username = ? and 1 = 1"; setContext("<jdbc-user-service id='myUserService' " + "data-source-ref='dataSource' " + "users-by-username-query='" + userQuery + "' " + "authorities-by-username-query='" + authoritiesQuery + "'/>" + DATA_SOURCE); JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext .getBean("myUserService"); assertThat(FieldUtils.getFieldValue(mgr,"usersByUsernameQuery")).isEqualTo(userQuery); assertThat(FieldUtils.getFieldValue(mgr, "authoritiesByUsernameQuery")).isEqualTo(authoritiesQuery); assertThat(mgr.loadUserByUsername("rod") != null).isTrue(); } @Test public void groupQueryIsParsedCorrectly() throws Exception { setContext("<jdbc-user-service id='myUserService' " + "data-source-ref='dataSource' " + "group-authorities-by-username-query='blah blah'/>" + DATA_SOURCE); JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext .getBean("myUserService"); assertThat(FieldUtils.getFieldValue(mgr, "groupAuthoritiesByUsernameQuery")).isEqualTo("blah blah"); assertThat((Boolean) FieldUtils.getFieldValue(mgr, "enableGroups")).isTrue(); } @Test public void cacheRefIsparsedCorrectly() { setContext("<jdbc-user-service id='myUserService' cache-ref='userCache' data-source-ref='dataSource'/>" + DATA_SOURCE + USER_CACHE_XML); CachingUserDetailsService cachingUserService = (CachingUserDetailsService) appContext .getBean("myUserService" + AbstractUserDetailsServiceBeanDefinitionParser.CACHING_SUFFIX); assertThat(appContext.getBean("userCache")).isSameAs(cachingUserService.getUserCache()); assertThat(cachingUserService.loadUserByUsername("rod")).isNotNull(); assertThat(cachingUserService.loadUserByUsername("rod")).isNotNull(); } @Test public void isSupportedByAuthenticationProviderElement() { setContext("<authentication-manager>" + " <authentication-provider>" + " <jdbc-user-service data-source-ref='dataSource'/>" + " </authentication-provider>" + "</authentication-manager>" + DATA_SOURCE); AuthenticationManager mgr = (AuthenticationManager) appContext .getBean(BeanIds.AUTHENTICATION_MANAGER); mgr.authenticate(new UsernamePasswordAuthenticationToken("rod", "koala")); } @Test public void cacheIsInjectedIntoAuthenticationProvider() { setContext("<authentication-manager>" + " <authentication-provider>" + " <jdbc-user-service cache-ref='userCache' data-source-ref='dataSource'/>" + " </authentication-provider>" + "</authentication-manager>" + DATA_SOURCE + USER_CACHE_XML); ProviderManager mgr = (ProviderManager) appContext .getBean(BeanIds.AUTHENTICATION_MANAGER); DaoAuthenticationProvider provider = (DaoAuthenticationProvider) mgr .getProviders().get(0); assertThat(appContext.getBean("userCache")).isSameAs(provider.getUserCache()); provider.authenticate(new UsernamePasswordAuthenticationToken("rod", "koala")); assertThat(provider .getUserCache().getUserFromCache("rod")).isNotNull().withFailMessage("Cache should contain user after authentication"); } @Test public void rolePrefixIsUsedWhenSet() { setContext("<jdbc-user-service id='myUserService' role-prefix='PREFIX_' data-source-ref='dataSource'/>" + DATA_SOURCE); JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext .getBean("myUserService"); UserDetails rod = mgr.loadUserByUsername("rod"); assertThat(AuthorityUtils.authorityListToSet(rod.getAuthorities())) .contains("PREFIX_ROLE_SUPERVISOR"); } private void setContext(String context) { appContext = new InMemoryXmlApplicationContext(context); } }