TL; DR Ihre Service-Definitionen unter den autoloading Definitionen in services.yml
verschieben und ändern Sie den Code WsseFactory
zu
$container
->setDefinition($providerId, new ChildDefinition(WsseProvider::class))
->setArgument('$userProvider', new Reference($userProvider))
;
Vollständige Erklärung. Der erste Fehler im bereitgestellten Code besteht darin, dass die Definitionen der Dienste den Autoloading-Zeilen vorangehen. Das automatische Laden überschreibt einfach die vorherigen Definitionen und verursacht den Fehler AuthenticationManagerInterface
. Durch Verschieben der folgenden Definitionen wird das Problem behoben. Die andere Möglichkeit, das Problem zu beheben, sind Aliasnamen wie @yceruto und @gintko.
Aber nur dieser Zug wird den Code trotz Ihrer Antwort nicht funktionieren lassen. Sie haben wahrscheinlich nicht bemerkt, wie etwas anderes geändert wurde, damit es funktioniert.
Das zweite Problem, der Fehler replaceArgument
, bezieht sich auf Symfonys Reihenfolge der Container-Kompilierung, wie richtig angenommen wurde. Die Bestellung wird in der PassConfig
Klasse definiert:
$this->optimizationPasses = array(array(
new ExtensionCompilerPass(),
new ResolveDefinitionTemplatesPass(),
...
$autowirePass = new AutowirePass(false),
...
));
ich die irrelevanten Pässe weggelassen. Die von der WsseFactory
erstellte security.authentication.provider.wsse.wsse_secured
-Definition wird zuerst erstellt. Dann ResolveDefinitionTemplatesPass
statt, und wird versuchen, die Argumente der Definition zu ersetzen und erhöhen die Cannot replace arguments
Ausnahme Sie bekam:
foreach ($definition->getArguments() as $k => $v) {
if (is_numeric($k)) {
$def->addArgument($v);
} elseif (0 === strpos($k, 'index_')) {
$def->replaceArgument((int) substr($k, strlen('index_')), $v);
} else {
$def->setArgument($k, $v);
}
}
Das Problem erscheint Ursache der Pass Definition::replaceArgument
für index_0
nennen. Da die Elterndefinition kein Argument an Position 0 hat, weder in der früheren services.xml
noch in der festen. AutowirePass
wurde noch nicht ausgeführt, die automatisch generierten Definitionen haben keine Argumente, die manuelle Definition hat nur das Argument $cachePool
.
Also das Problem beheben Sie lieber verwenden:
->setArgument(0, new Reference($userProvider)); //proposed by @yceruto
->replaceArgument('$userProvider', new Reference($userProvider)); //proposed by @gintko
->setArgument('$userProvider', new Reference($userProvider)); // by me
Alle von ihnen werden die Anrufe von Definition::addArgument
oder Definition::setArgument
mit sich bringen und ausarbeitet. Es gibt nur den kleinen Unterschied: - setArgument(0, ...
konnte für einige andere Szenarien nicht funktionieren; - Ich mag ->setArgument('$userProvider'
mehr als ->replaceArgument('$userProvider'
wegen Semantik. Nichts zu ersetzen noch!
Hoffe die Details, warum das Problem jetzt klar erscheint.
PS. Es gibt auch einige andere lustige Wege, um das Problem zu überwinden.
Befestigen Sie die Config ein wenig:
AppBundle\Security\Authentication\Provider\WsseProvider:
arguments:
0: ''
$cachePool: '@cache.app'
public: false
Oder einen Alias von Symfony\Component\Security\Core\User\UserProviderInterface
Set für Sie die autowire den Rest erledigen zu lassen.
$container
->setDefinition($providerId, new ChildDefinition(WsseProvider::class))
// ->replaceArgument(0, new Reference($userProvider))
;
$container
->setAlias('Symfony\Component\Security\Core\User\UserProviderInterface',$userProvider)
;
Haben Sie dieses Repo gezogen und versuchen, es zu reparieren? Weil nichts in Ihrer Antwort die grundlegende Implementierung aus dem Repo beeinflussen würde. Ich habe eine Version, die FOS User Bundle verwendet, aber es funktioniert nicht. Es hat die Konfiguration bereits an Ort und Stelle. –
@JakeN: Bitte sehen Sie meine Bearbeitung. Ich habe die Antwort komplett geändert. – tukan