[Security] Session concurrency control

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #7845
| License       | MIT
| Doc PR        | no

This PR is based on #786 by @paschke. The most important changes from this PR are listed below:

* No change is done in `Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface` to maintain BC.
* The SQL for the upsert in `Symfony\Bridge\Doctrine\Security\SessionRegistry\SessionRegistryStorage` is borrowed from `Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler`
* A new `Symfony\Component\Security\Http\Session\CompositeSessionAuthenticationStrategy` class exits to wrap the actual SessionAuthenticationStrategy, and to split the concurrency control in two steps: the first one checks the concurrency, the last one registers the session information in the registry.
* The new configuration parameter `firewalls.secured_area.session_concurrency.error_if_maximum_exceeded` allows you to configure the default behaviour when session concurrency is detected: to avoid a new login, or to expire the oldest sessions.
* The `Symfony\Component\Security\Http\Firewall\ConcurrentSessionListener` is renamed to `Symfony\Component\Security\Http\Firewall\ExpiredSessionListener`
* We have some unit and functional tests now.

If you call `->expireNow()`, the method `->isExpired()` could return false within the same second.

Maybe the check should be `$this->getExpired()->getTimestamp() <= true()`.

What do you think about?