Description
I just encountered a problem with property overriding when I tried to override the client-id
of the opaque-token property of the resourceserver
configuration in Spring Security.
In my code I am loading the value as following via an @Value
annotation, in one of my configuration classes:
@Value("${spring.security.oauth2.resourceserver.opaque-token.client-id}")
This is in accordance with the documented naming convention for the key as can be seen here:
https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/opaque-token.html#oauth2resourceserver-opaque-introspectionuri
Please observe, that both opaque-token
and client-id
use a hyphen in their name.
If I place the correct value for this key directly into the application.yaml
file then everything works as expected. However, I wanted to override this value using the relaxed binding rules for environment variables and used the following variable name:
SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUE_TOKEN_CLIENT_ID
However this did now work, and after some debugging I found that specifically the ReactiveOAuth2ResourceServerOpaqueTokenConfiguration
(see https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java) was not receiving the overwritten value, and it appears that the reason is, that this class is using a different key format for loading the resource server properties, which is:
@ConditionalOnProperty(name = "spring.security.oauth2.resourceserver.opaquetoken.introspection-uri")
Observe, that there the opaquetoken
is not using a hyphen. I then realized, that according to the relaxed binding convention, I should maybe remove the underscores in placed where a hyphen is used and I changed the environment variable name to the following:
SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENTID
This did not work for two reasons:
- The client-id was no longer correctly bound, since I removed the underscore also from CLIENT_ID.
- My own annotation was still using the
opaque-token
format (with a hyphen).
After some experiments with different placements of underscores and hyphens, I found that the only working configuration for me was the following:
- In my
application.yaml
file I had to remove the hyphen fromopaque-token
and define it asopaquetoken
(which is different from the documented format in the link at the top). - In my own configuration classes I had to adjust the value annotation and load the client id via
@Value("${spring.security.oauth2.resourceserver.opaquetoken.client-id}")
- I had to change the environment variable and use the following format:
SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENT_ID
(not that theOPAQUETOKEN
part is without underscore, but theCLIENT_ID
part uses an underscore, which strictly speaking is not how the relaxed binding convention for environment variables is documented.
The original reason, why I had to look into this, is because I was being hit by the same error as described in this issue, since the client-id was not correctly configured in my resource server:
#7858
To Reproduce
- Configure a resource server with spring security.
- Define a default opaque-token.client-id in the application.yaml for the resource server
- Then try to override the client-id of the opaque-token.client-id using an environment variable
- Observer that the old client-id is being used.
Expected behavior
- Overriding works correctly
- Consistent use of
opaque-token
vs.opaquetoken
in documentation and internal implementation.
May I request a clarification on the following items:
- If the use of
opaquetoken
overopaque-token
in theReactiveOAuth2ResourceServerOpaqueTokenConfiguration
is considered correct. - If the recommended format of the relaxed binding environment variable name should be:
a)SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENTID
or
b)SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENT_ID
or
c)SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUE_TOKEN_CLIENT_ID
or
Only b) worked for me. - If I should follow the documentation and use
opaque-token
in theapplication.yaml
or if ratheropaquetoken
should be used.