diff --git a/config/src/main/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParser.java index a0d7de83f65..9cbe4f93cd9 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 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. @@ -42,7 +42,7 @@ protected String getBeanClassName(Element element) { @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String dataSource = element.getAttribute(ATT_DATA_SOURCE); - if (dataSource != null) { + if (StringUtils.hasText(dataSource)) { builder.addPropertyReference("dataSource", dataSource); } else { diff --git a/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java index 41395cd8b41..7a07eeb69d3 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -19,7 +19,10 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.w3c.dom.Element; +import org.xml.sax.SAXParseException; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; +import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.CachingUserDetailsService; import org.springframework.security.authentication.ProviderManager; @@ -33,6 +36,7 @@ import org.springframework.security.util.FieldUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; /** @@ -160,6 +164,38 @@ public void rolePrefixIsUsedWhenSet() { assertThat(AuthorityUtils.authorityListToSet(rod.getAuthorities())).contains("PREFIX_ROLE_SUPERVISOR"); } + @Test + public void testEmptyDataSourceRef() { + // @formatter:off + String xml = "" + + " " + + " " + + " " + + ""; + assertThatExceptionOfType(BeanDefinitionParsingException.class) + .isThrownBy(() -> setContext(xml)) + .withFailMessage("Expected exception due to empty data-source-ref") + .withMessageContaining("data-source-ref is required for jdbc-user-service"); + // @formatter:on + } + + @Test + public void testMissingDataSourceRef() { + // @formatter:off + String xml = "" + + " " + + " " + + " " + + ""; + assertThatExceptionOfType(XmlBeanDefinitionStoreException.class) + .isThrownBy(() -> setContext(xml)) + .withFailMessage("Expected exception due to missing data-source-ref") + .havingRootCause() + .isInstanceOf(SAXParseException.class) + .withMessageContaining("Attribute 'data-source-ref' must appear on element 'jdbc-user-service'"); + // @formatter:on + } + private void setContext(String context) { this.appContext = new InMemoryXmlApplicationContext(context); }