/*
* 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 static org.assertj.core.api.Assertions.*;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
import org.springframework.security.util.FieldUtils;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.junit.Test;
import org.junit.After;
import java.util.List;
/**
* Tests for {@link AuthenticationProviderBeanDefinitionParser}.
*
* @author Luke Taylor
*/
public class AuthenticationProviderBeanDefinitionParserTests {
private AbstractXmlApplicationContext appContext;
private UsernamePasswordAuthenticationToken bob = new UsernamePasswordAuthenticationToken(
"bob", "bobspassword");
@After
public void closeAppContext() {
if (appContext != null) {
appContext.close();
}
}
@Test
public void worksWithEmbeddedUserService() {
setContext(" <authentication-provider>"
+ " <user-service>"
+ " <user name='bob' password='bobspassword' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
getProvider().authenticate(bob);
}
@Test
public void externalUserServiceRefWorks() throws Exception {
appContext = new InMemoryXmlApplicationContext(
" <authentication-manager>"
+ " <authentication-provider user-service-ref='myUserService' />"
+ " </authentication-manager>"
+ " <user-service id='myUserService'>"
+ " <user name='bob' password='bobspassword' authorities='ROLE_A' />"
+ " </user-service>");
getProvider().authenticate(bob);
}
@Test
public void providerWithBCryptPasswordEncoderWorks() throws Exception {
setContext(" <authentication-provider>"
+ " <password-encoder hash='bcrypt'/>"
+ " <user-service>"
+ " <user name='bob' password='$2a$05$dRmjl1T05J7rvCPD2NgsHesCEJHww3pdmesUhjM3PD4m/gaEYyx/G' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
getProvider().authenticate(bob);
}
@Test(expected = BeanDefinitionParsingException.class)
public void bCryptAndSaltSourceRaisesException() throws Exception {
appContext = new InMemoryXmlApplicationContext(
""
+ " <authentication-manager>"
+ " <authentication-provider>"
+ " <password-encoder hash='bcrypt'>"
+ " <salt-source ref='saltSource'/>"
+ " </password-encoder>"
+ " <user-service>"
+ " <user name='bob' password='$2a$05$dRmjl1T05J7rvCPD2NgsHesCEJHww3pdmesUhjM3PD4m/gaEYyx/G' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>"
+ " </authentication-manager>"
+ " <b:bean id='saltSource' class='"
+ ReflectionSaltSource.class.getName() + "'>"
+ " <b:property name='userPropertyToUse' value='username'/>"
+ " </b:bean>");
}
@Test
public void providerWithMd5PasswordEncoderWorks() throws Exception {
setContext(" <authentication-provider>"
+ " <password-encoder hash='md5'/>"
+ " <user-service>"
+ " <user name='bob' password='12b141f35d58b8b3a46eea65e6ac179e' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
getProvider().authenticate(bob);
}
@Test
public void providerWithShaPasswordEncoderWorks() throws Exception {
setContext(" <authentication-provider>"
+ " <password-encoder hash='{sha}'/>"
+ " <user-service>"
+ " <user name='bob' password='{SSHA}PpuEwfdj7M1rs0C2W4ssSM2XEN/Y6S5U' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
getProvider().authenticate(bob);
}
@Test
public void providerWithSha256PasswordEncoderIsSupported() throws Exception {
setContext(" <authentication-provider>"
+ " <password-encoder hash='sha-256'/>"
+ " <user-service>"
+ " <user name='bob' password='notused' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
ShaPasswordEncoder encoder = (ShaPasswordEncoder) FieldUtils.getFieldValue(
getProvider(), "passwordEncoder");
assertThat(encoder.getAlgorithm()).isEqualTo("SHA-256");
}
@Test
public void passwordIsBase64EncodedWhenBase64IsEnabled() throws Exception {
setContext(" <authentication-provider>"
+ " <password-encoder hash='md5' base64='true'/>"
+ " <user-service>"
+ " <user name='bob' password='ErFB811YuLOkbupl5qwXng==' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>");
getProvider().authenticate(bob);
}
@Test
public void externalUserServicePasswordEncoderAndSaltSourceWork() throws Exception {
appContext = new InMemoryXmlApplicationContext(
" <authentication-manager>"
+ " <authentication-provider user-service-ref='customUserService'>"
+ " <password-encoder ref='customPasswordEncoder'>"
+ " <salt-source ref='saltSource'/>"
+ " </password-encoder>"
+ " </authentication-provider>"
+ " </authentication-manager>"
+
" <b:bean id='customPasswordEncoder' "
+ "class='org.springframework.security.authentication.encoding.Md5PasswordEncoder'/>"
+ " <b:bean id='saltSource' "
+ " class='"
+ ReflectionSaltSource.class.getName()
+ "'>"
+ " <b:property name='userPropertyToUse' value='username'/>"
+ " </b:bean>"
+ " <b:bean id='customUserService' "
+ " class='org.springframework.security.provisioning.InMemoryUserDetailsManager'>"
+ " <b:constructor-arg>"
+ " <b:props>"
+ " <b:prop key='bob'>f117f0862384e9497ff4f470e3522606,ROLE_A</b:prop>"
+ " </b:props>" + " </b:constructor-arg>"
+ " </b:bean>");
getProvider().authenticate(bob);
}
// SEC-1466
@Test(expected = BeanDefinitionParsingException.class)
public void exernalProviderDoesNotSupportChildElements() throws Exception {
appContext = new InMemoryXmlApplicationContext(
" <authentication-manager>"
+ " <authentication-provider ref='aProvider'> "
+ " <password-encoder ref='customPasswordEncoder'/>"
+ " </authentication-provider>"
+ " </authentication-manager>"
+ " <b:bean id='aProvider' class='org.springframework.security.authentication.TestingAuthenticationProvider'/>"
+ " <b:bean id='customPasswordEncoder' "
+ " class='org.springframework.security.authentication.encoding.Md5PasswordEncoder'/>");
}
private AuthenticationProvider getProvider() {
List<AuthenticationProvider> providers = ((ProviderManager) appContext
.getBean(BeanIds.AUTHENTICATION_MANAGER)).getProviders();
return providers.get(0);
}
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext("<authentication-manager>"
+ context + "</authentication-manager>");
}
}