SecurityExtension::createFirewalls() is responsible for setting user
providers in the ContextListener constructor arguments, but it does so using
only the providers that were defined alongside the particular firewall
configuration.  If you your combined application config has multiple
security.config blocks, each with their own firewalls that you expect to be
merged together, you'll find previous UserProviders missing at runtime.
This is a problem that a few of us have encountered while trying to maintain
extra security.config blocks for our test environments, which sit atop a
basic configuration used by all environments (e.g. dev, test, prod).

I came up with a couple of alternative solutions, but I'd like to get some
feedback before deciding which to submit as a pull request.  The code to fix
is right below the comment "// make the ContextListener aware of the
configured user providers" in:

https://github.com/fabpot/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/SecurityExtension.php

As-is, this code replaces the argument with whatever the current providers
are, but we can instead merge using one of the following methods:

   1. Check References in the pre-existing args (if any) and only add
   providers that have new ID's, disregarding conflicts.  This might cause
   unexpected behavior for firewalls in the current config block that depend on
   a "conflicting" UserProvider, as they will instead use the pre-existing
   version.
   2. Do the reverse and have new providers override pre-existing
   conflicts.  This might cause unexpected behavior for firewalls of previous
   config blocks (vice versa to the concern in #1).
   3. Throw a RuntimeException if any new provider ID's conflict with
   References in the pre-existing args array.  This is similar to the spirit of
   createUserProviders(), which throws an exception for ID conflicts, but is
   most likely to cause BC issues for existing project configurations.
   4. Don't have createFirewalls() set ContextListener's arguments.  When
   createUserDaoProvider() creates provider definitions, we can tag them.  A
   compiler pass run after all configs have loaded will set ContextListener's
   arguments once.  This will rely on the existing behavior of
   createUserDaoProvider(), which is "later definitions overwrite
   pre-existing".

I'm aware of the pending mass-refactoring for core extensions to only
execute configLoad() methods once.  That will certainly help address this,
if only by moving the decision-making into the method responsible for
merging multiple security.config blocks.  In light of that, I'm leaning
towards #4, as I think its "fix" would be equally valid both before and
after that refactoring.

-- 
jeremy mikola

-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to