Issue 1:
There seems to be a problem when updating ACL when using object field aces. It is fairy simply to reproduce inside a test controller:

create a simple domain object:

$demoObj = new Demo();
$demoObj->setId(2);

$oid = ObjectIdentity::fromDomainObject($demoObj);
$fieldName = "name";

give the object a simple ROLE based ACL:

$aclProvider = $this->get('security.acl.provider');
$acl = $aclProvider->createAcl($oid);

$roleUser = new RoleSecurityIdentity('ROLE_USER');
$mask = new MaskBuilder(4); // 4 = EDIT

$acl->insertobjectFieldAce($fieldName, $roleUser, $mask->get());

$aclProvider->updateAcl($acl);

add another ROLE to the ACL:

$acl = $aclProvider->findAcl($oid);
$roleUser = new RoleSecurityIdentity('ROLE_FOO');
$mask = new MaskBuilder(4); // 4 = EDIT

$acl->insertobjectFieldAce($fieldName, $roleUser, $mask->get());
$aclProvider->updateAcl($acl);

add one more ROLE to the ACL:

$acl = $aclProvider->findAcl($oid);
$roleUser = new RoleSecurityIdentity('ROLE_BAR');
$mask = new MaskBuilder(4); // 4 = EDIT

$acl->insertobjectFieldAce($fieldName, $roleUser, $mask->get());
$aclProvider->updateAcl($acl);

running step 4 produces the following:

An exception occurred while executing 'UPDATE acl_entries SET ace_order
= 1 WHERE id = 40':

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'19-22-name-1' for key
'UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4'

If you remove the offending index from the database, the update works perfectly (the ace_order), so the problem seems to be that Symfony is not updating the ACL items in the correct order.

The above does not affect class field aces.

There is a second issue related to the above where the following throws the same execption:

$index = 0;
$acl->deleteObjectFieldAce($index, $fieldName);
$acl->insertObjectFieldAce($fieldName, $roleUser, $mask->get());
$aclProvider->updateAcl($acl);

there is a workaround by doing:

$index = 0;
$acl->deleteObjectFieldAce($index, $fieldName);
$aclProvider->updateAcl($acl);
$acl->insertObjectFieldAce($fieldName, $roleUser, $mask->get());
$aclProvider->updateAcl($acl);

Once again this does not affect class field aces.

Issue 2:
Problem:

Session cookie is not present (deleted, expired, invalid, etc)

RememberMe cookie is present

User is logging out

RememberMe cookie is not deleted

Alternatively:

Session cookie is not present (deleted, expired, invalid, etc)

User is logging out

No LogoutHandlerInterface implementation is called (because there is no token)

After debugging I see what happens:

security.logout_listener is created

security.logout_listener is given LogoutHandlerInterfaces: 1, 2, 3

authentication listeners are created from factories, including RememberMeFactory

RememberMeFactory adds its own LogoutHandlerInterface

Security listeners are merged

Firewall iterates over listeners and stops on the first giving Response.

Problem? Listeners are called in this order: ChannelListener, ContextListener, ContainerAwareEventDispatcher, LogoutListener, UsernamePasswordFormAuthenticationListener, RememberMeListener, AnonymousAuthenticationListener, AccessListener.

So if the user doesn't have a session cookie, LogoutListener doesn't call any LogoutHandlerInterfaces, because there is no token (yet).

IMHO LogoutListener should be called last, after other listeners, which might authenticate user before he/she is logged out. Otherwise none of the handlers are called.

In my situation it is crucial that RememberMeServices (as LogoutHandlerInterface) + CookieClearingLogoutHandler get called, because Symfony co–exists with non–Symfony app.

I don't know what's the correct solution, but as a fast hack it could work to:

override LogoutListener and call LogoutHandlerInterfaces manually with a dummy TokenInterface if there is no token yet,

override LogoutListener and do custom actions here (but I believe LogoutHandlerInterfaces should be used, as they might contain important logic),

override LogoutSuccessHandlerInterface, but same problem as above,

override FirewallMap to change the order of listeners (as it should have already been done in SecurityExtension?).