Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Honor @Primary for UserDetailsService and UserDetailsPasswordService in InitializeUserDetailsBeanManagerConfigurer #18015

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

Open
siva-sai-udaygiri wants to merge 4 commits into spring-projects:main
base: main
Choose a base branch
Loading
from siva-sai-udaygiri:honor-primary-uds-17902

Conversation

@siva-sai-udaygiri
Copy link

@siva-sai-udaygiri siva-sai-udaygiri commented Oct 6, 2025

Motivation

In scenarios where multiple UserDetailsService or UserDetailsPasswordService beans
are defined, Spring may raise NoUniqueBeanDefinitionException or select the wrong
bean without explicit resolution.

Changes

  • Added @Primary to UserDetailsService and UserDetailsPasswordService beans in
    InitializeUserDetailsBeanManagerConfigurer
  • Ensures deterministic bean selection

Issue Reference

Fixes gh-17902

Testing

  • Added a test in InitializeUserDetailsBeanManagerConfigurerTests to validate
    resolution when multiple candidates are present
  • Verified that all existing tests pass with ./gradlew check

Notes

  • No breaking changes
  • Consistent with Spring idioms for bean resolution

@jzheaux jzheaux force-pushed the honor-primary-uds-17902 branch from 2382273 to d4e00e4 Compare October 20, 2025 21:16
@jzheaux jzheaux self-assigned this Oct 20, 2025
@jzheaux jzheaux added in: config An issue in spring-security-config type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 20, 2025
Copy link
Contributor

@jzheaux jzheaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @siva-sai-udaygirl, for the PR! I've left some feedback inline.


PasswordEncoder passwordEncoder = getBeanIfUnique(PasswordEncoder.class);
// Also resolve UDPS via container so @Primary is honored
UserDetailsPasswordService passwordManager = getAutowireCandidateOrNull(UserDetailsPasswordService.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this changes the existing semantics by calling getIfAvailable instead of getIfUnique. The ObjectProvider JavaDoc implies that it accounts for @Primary:

	/**
	 * Return an instance (possibly shared or independent) of the object
	 * managed by this factory.
	 * @return an instance of the bean, or {@code null} if not available or
	 * not unique (i.e. multiple candidates found **with none marked as primary**)
	 * @throws BeansException in case of creation errors
	 * @see #getObject()
	 */

Can you confirm with unit tests that changing to getIfAvailable is necessary to support @Primary?

Copy link
Author

@siva-sai-udaygiri siva-sai-udaygiri Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @jzheaux! I added unit tests to show why we need to rely on the container’s autowire-candidate resolution to honor @primary.

• With getIfUnique(...) when there are two UserDetailsService beans and one is @primary, it still returns null (multiple names), so the global AuthenticationManager isn’t configured.
• With getIfAvailable(...) it delegates to autowire-candidate selection (same as normal injection), so the @primary bean is chosen, and the AuthenticationManager is configured.

New tests:

  • whenMultipleUdsAndOneResolvableCandidate_thenPrimaryIsAutoWired
  • whenMultipleUdsAndNoSingleCandidate_thenSkipAutoWiring

Location: spring-security-config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurerTests.java

This keeps behavior the same for the single-bean case, and for multiple beans without a single resolvable candidate we still skip auto-wiring (and log). Please take another look and let me know if you’d prefer a different approach.

siva-sai-udaygiri and others added 3 commits October 20, 2025 17:08
Signed-off-by: Siva Sai Udayagiri <udayagirishivasai@gmail.com>
This commit rearranges the branches to reduce nesting
Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com>
Given that the codebase uses getBeanIfUnique logic in many places,
it is a little noisy to clarify how it works in just this location.
Instead, the previous commit simplifies the branching logic, reducing
the need for clarification of what could otherwise be surprising.
Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com>
@jzheaux jzheaux force-pushed the honor-primary-uds-17902 branch from d4e00e4 to 581d666 Compare October 20, 2025 23:09
...in InitializeUserDetailsBeanManagerConfigurer (spring-projects#17902)
Signed-off-by: Siva Sai Udayagiri <udayagirishivasai@gmail.com>
Copy link
Author

siva-sai-udaygiri commented Oct 22, 2025
edited
Loading

Implemented getAutowireCandidateOrNull(...) to honor @primary.
Added unit tests covering: (a) multiple UDS with one @primary → auto-wired; (b) multiple UDS with no single candidate → skipped; (c) single UDS unchanged.
Rebased on latest main and all config checks pass locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jzheaux jzheaux jzheaux requested changes

Labels

in: config An issue in spring-security-config type: bug A general bug

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

InitializeUserDetailsBeanManagerConfigurer should respect primary flag

AltStyle によって変換されたページ (->オリジナル) /