0

I have two spring profiles that are independent from each other, like below:

<beans profile="prof1">
    <security:authentication-manager id="authenticationManager" erase-credentials="true">
        <security:authentication-provider ref="1" />
        <security:authentication-provider ref="2" />
        <security:authentication-provider ref="3" />
    </security:authentication-manager>
</beans>

<beans profile="prof2" >
    <security:authentication-manager id="authenticationManager" erase-credentials="true">
        <security:authentication-provider ref="0" />
        <security:authentication-provider ref="1" />
        <security:authentication-provider ref="2" />
        <security:authentication-provider ref="3" />
    </security:authentication-manager>
</beans>

For instance, I can enable profile in the following way:

|prof1|prof2|
|true |true |
|true |false|
|false|true |
|false|false|

When the last option is specified spring complain that authentication-manager is missed.

In order to fix this I looked for something like "optional reference to spring bean".

Namely the idea was to extract manager from the profile like below:

 <security:authentication-manager id="authenticationManager" erase-credentials="true">
            <security:authentication-provider ref="0-optional-reference" />
            <security:authentication-provider ref="1" />
            <security:authentication-provider ref="2" />
            <security:authentication-provider ref="3" />
        </security:authentication-manager>

Then make bean with name "0" as optional bean. I've found the following post Optional Spring bean references but it looks like any options does not work for me because I cannot replace "ref" attribute with "value" because of spring xsd.

It would be good to know any options how can I specify optional bean for authentication-provider spring tag.

Community
  • 1
  • 1
fashuser
  • 2,152
  • 3
  • 29
  • 51

1 Answers1

0

Spring complains because when neither profiles are active, the beans definitions declared in the prof1 and prof2 <beans> blocks are not taken into account and therefore not loaded in the BeanFactory. So at runtime, Spring Security doesn't find any bean of type AuthenticationManager and complains.

What you could do is declare a "default" AuthenticationManager in a new <beans> block that would be active only if neither prof1 nor prof2 are active :

<beans profile="!prof1 !prof2">
    <security:authentication-manager id="authenticationManager">
    ...
    </security:authentication-manager>
</beans>
Olivier Croisier
  • 6,139
  • 25
  • 34
  • Thanks Olivier for prompt answer. I am just thinking about the case when both profiles are active. And which one will be considered valid. It looks like both declaration , will be valid. – fashuser Mar 21 '16 at 15:02
  • When both profiles are active, the 2 `AuthenticationManagers` become available for injection and have equal "weight", which can lead to Spring complaining that it found multiple implementations of a given bean type. To solve that problem, you can mark either one as "primary" : ``, so that it takes precedence over during injection lookup. – Olivier Croisier Mar 21 '16 at 15:05
  • I've tried this for beans tag, but it looks like it is not allowed by spring xsd to set such attribute. Will be it possible to specify any other attribute instead? – fashuser Mar 21 '16 at 15:11
  • The "primary" attribute must be set on a `` tag, not ``. Now that you mention it, I'm not sure if the specialized `` tag can bear it directly (I cannot test that right now, sorry). If not, you will have to resort to declaring the authentication manager "by hand" using plain old bean declarations. – Olivier Croisier Mar 21 '16 at 15:13
  • Yes, but I don't have bean, only the context that specified above. Namely authentication-manager inside of the beans. – fashuser Mar 21 '16 at 15:15