Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document more clearly that username and password are not used when spring.data.redis.url is set #41231

Closed
alexisgayte opened this issue Jun 25, 2024 · 12 comments
Assignees
Labels
type: documentation A documentation update
Milestone

Comments

@alexisgayte
Copy link

alexisgayte commented Jun 25, 2024

https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetails.java#L41

Configuration via URL doesn't allow username and password to be passed separately.
This is problematic in a prod environment where these data need to be encrypted.

I know there is a workaround : using params directly however if I recall Lettuce allows it.
The fix would be if username is null/empty try to pick the param.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 25, 2024
@alexisgayte alexisgayte changed the title RedisAutoConfiguration doesn't allow to pass username + password outside the url RedisAutoConfiguration via url doesn't allow to pass username + password outside the url Jun 25, 2024
@wilkinsona
Copy link
Member

wilkinsona commented Jun 25, 2024

This is an intentional design choice. In the past, we tried to combine multiple properties when configuring RabbitMQ but it was confusing for users and a source of subtle bugs. We wouldn't want to open up the possibility with Redis.

Making a change here would also be backwards incompatible as we currently document that the url overrides the host, port, username, and password:

You can either store the whole URL has a secret that's retrieved from an encrypted store, or use the separate host, port, username, and password properties and handle the username and password as secrets.

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Jun 25, 2024
@wilkinsona wilkinsona added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 25, 2024
@alexisgayte
Copy link
Author

alexisgayte commented Jun 26, 2024

Sorry for picking this up again, I still fell there is an bug/issue/missed there.

In your case (which is less lenient) we probably should manage it via error.
if url set and password/username set --> throw an error.

The current situation is ambiguous. I also understand that is not really a priority.

@wilkinsona
Copy link
Member

wilkinsona commented Jun 26, 2024

In your case (which is less lenient) we probably should manage it via error.

Yeah, that would be nice. We have MutuallyExclusiveConfigurationPropertiesException that can be thrown when multiple properties that should be mutually exclusive have been set at the same time. Unfortunately, we can't use it here as it only works well when it's added at the same time as the properties.

At the moment, if someone has host, port, username and password set somewhere, they can override them by setting the uri property. Unfortunately, there's no good way to unset a property so if we change the implementation to instead throw a MutuallyExclusiveConfigurationPropertiesException exception, we'd break things for them.

@alexisgayte
Copy link
Author

Just to clarify the reason why I got into it, as I realised it is important and not documented.

When setting redis I got the url from a cloud provider without user/password. (user password are set separately).

I looked at spring.data.redis configuration (autocompleted), picked "url" and populate it then I did the same for "username" and "password".

This was looking fine as database are configured the same way. But then when running the app, user and password weren't populated.
That was due to this ticket. I believe I am not going to be the only one to fall into it.

@philwebb philwebb changed the title RedisAutoConfiguration via url doesn't allow to pass username + password outside the url Document that username and password are not used when 'spring.data.redis.url' is set Jun 28, 2024
@philwebb philwebb added type: documentation A documentation update and removed status: declined A suggestion or change that we don't feel we should currently apply labels Jun 28, 2024
@philwebb philwebb added this to the 3.2.x milestone Jun 28, 2024
@philwebb philwebb reopened this Jun 28, 2024
@philwebb
Copy link
Member

I've reopened this issue and repurposed it to improve the documentation.

@wilkinsona
Copy link
Member

It's already documented in the configuration property metadata.

I looked at spring.data.redis configuration (autocompleted), picked "url" and populate it then I did the same for "username" and "password".

Given that this is how @alexisgayte ended up with the faulty configuration, I'm not sure that more documentation would have helped.

@alexisgayte
Copy link
Author

alexisgayte commented Jun 28, 2024

That was the end of my journey. Now that I try to remember my walkthrough, I googled about redis and spring boot (trying to do the same now) and I couldn't find any good documentation to configure it using spring boot. - https://docs.spring.io/spring-data/redis/reference/redis/getting-started.html - this one is more for spring data which is good but not spring-boot.

then I picked baeldung (linked to spring I believe, very good content) https://www.baeldung.com/spring-data-redis-tutorial -

which bring me to create the ConnectionFactory and all, but when I had a look at the redis auto config class - for some reason, there were a deprecated method somewhere setPassword or setSsl which was tricky to set with the new implementation - I realised that everything was already built and nicely done via simple configuration spring.data.redis.
Then I use it to configure it and ended to create this ticket regarding the url + password.

Probably not many people got into this issue, as they probably redefine all beans following baeldung.

So yes documentation would definitely help at the first place. baeldung is not super up to date on it, probably more 2.7.x.

@wilkinsona
Copy link
Member

Spring Boot's docs for working with Spring Data Redis are here. They have an example that uses the host, port, username, and password properties:

spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.database=0
spring.data.redis.username=user
spring.data.redis.password=secret

Perhaps we could show an equivalent using the uri property and note the overriding behavior.

@alexisgayte
Copy link
Author

I definitely didn't reach the page via google.

I am not sure if that would have help to have a link here [ https://docs.spring.io/spring-data/redis/reference/redis/getting-started.html ].

One of the reason why I was going for the url too was for the protocol configuration redis:// - rediss:// - just saying.

@alexisgayte
Copy link
Author

alexisgayte commented Jun 29, 2024

Hum,
I am afraid to say it, but I just had another look at it,
wondering if the url protocol (ssl) is taken into account. Or at least it is treated differently than the other parameters.

also I had a look with the other data parameters and it is inconsistent. for example :

spring.neo4j.uri=bolt://my-server:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
spring.elasticsearch.uris=https://search.example.com:9200
spring.elasticsearch.socket-timeout=10s
spring.elasticsearch.username=user
spring.elasticsearch.password=secret

May be just may be considering removing/deprecating the spring.data.redis.url is the way to go.

@wilkinsona
Copy link
Member

Those two examples aren't quite the same as Redis as there's no separate host and port properties, but I take your point nonetheless. I've opened #41280 so that we can review things across all of our auto-configurations. In the meantime, we can use this issue to improve the documentation for the current situation with Redis.

@wilkinsona wilkinsona changed the title Document that username and password are not used when 'spring.data.redis.url' is set Document more clearly that username and password are not used when spring.data.redis.url is set Jul 1, 2024
@quaff
Copy link
Contributor

quaff commented Jul 2, 2024

Configuration via URL doesn't allow username and password to be passed separately. This is problematic in a prod environment where these data need to be encrypted.

You can use placeholder as workaround:

spring.data.redis.url: redis://${spring.data.redis.username}:${spring.data.redis.password}@example.com:6379

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

6 participants