This issue is similar to #8453
I'm using Spring Security 5.4.5.
The placeholders in
I have a XML configuration containig:
<security:provider provider-id="..."
....
/>
Placeholders are resolved if used in a bean tag.
Comment From: jzheaux
Thanks for the report, @florinco. Since this feature has already been added, I think we'd need to see a sample to understand why it isn't working for you.
Would you be able to provide a minimal sample demonstrating the issue you are experiencing?
Comment From: florinco
Thanks for reply Josh.
Basically you can use the test case from #8453 (commit 875c323f24e3a6a2ef7c2c6036bef177ad8d83df) but instead of setting the placeholders as environment variables:
1. write them in an placeholders.properties file
2. link the properties file to ClientRegistrationsBeanDefinitionParserTests-ClientPlaceholders.xml via
I can confirm that the placeholders are resolved if I write them as environmental variables. They are not resolved if I store them in a .property file.
Comment From: jgrandja
@florinco The <context:property-placeholder> registers a PropertySourcesPlaceholderConfigurer @Bean, which ultimately resolves ${...} placeholders within bean definition (<b:bean ..>) property values.
The key point here is that the resolution applies only to the <b:bean ..> namespace. The <client-registrations> element is in the <security> namespace, so the PropertySourcesPlaceholderConfigurer will not apply the resolution.
You need to ensure the properties are available in the Environment, e.g. System.setProperty("oauth2.client.id", "github-client-id").
I'm going to close this issue as the behaviour is expected.
Comment From: nathan-hook
My apologies of digging up an issue that has been closed for over a year, but I am having a terrible time getting our client -id and client-secrets values into our application securely.
From my limited understanding, it seems as though the environment variables (via $ docker exec <container-id> env) and the system property via command line (via $ ps -aux) both leak secrets.
Is there an example of how to use System.setProperty("oauth2.client.id", "github-client-id") that reads from a properties file, but is early enough in the application startup so that system properties are there prior to the <security> namespace is instantiated?
Or is there another way to inject secrets into a spring java application that won't leak secrets that I'm missing?
I am grateful for your time and all your work. It has saved us a tremendous amount of time.
Comment From: jgrandja
@nathan-hook
Is there an example of how to use System.setProperty("oauth2.client.id", "github-client-id")
The test ClientRegistrationsBeanDefinitionParserTests.parseWhenClientPlaceholdersThenResolvePlaceholders() demonstrates this. This enhancement was added in gh-8453 via commit 17f15402800bae16f68ef7a6328f4e2062df6a51
Comment From: ychernysh
Hi @jgrandja , does this solution work only for properties supplied via JVM properties? I want my properties to be supplied from a factory-method created bean like this:
<bean id="appProperties" class="org.example.config.PropertiesFactory" factory-method="getProperties"/>
<context:property-placeholder properties-ref="appProperties"/>
package org.example.config;
import java.util.Properties;
public class PropertiesFactory {
public static Properties getProperties() {
Properties properties = new Properties();
properties.setProperty("person.name", "Alex");
properties.setProperty("client.id", "my-client-id");
return properties;
}
}
But this doesn't work. The property is not resolved here:
<client-registration client-id="${client.id}" ... />
But it is still resolved in common beans:
<bean id="person" class="org.example.model.Person">
<constructor-arg name="name" value="${person.name}"/>
</bean>
I'm not setting the property via System.setProperty, I want them to be created in the factory method above. Is that possible? Am I doing anything wrong? I'm on the Spring Security 6.4.1.
Thanks!