New in Symfony 2.6: Security component improvements
October 2, 2014 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Deprecated the security.context service
This is one of the major changes introduced by Symfony 2.6. Fortunately, it won't affect your applications because it maintains the backwards compatibility. In any case, to prepare for future Symfony versions, you should start learning the new way to deal with security.
The reason for this change is that when you inject the SecurityContext
in other services, specially those related to Doctrine, you may introduce a
circular reference that ends up in an exception.
After some community discussions, it was decided that SecurityContext
gives
too many dependencies to retrieve a simple Token/User object. That's why, starting
with Symfony 2.6, the security.context
service has been deprecated and split
into two new services: security.authorization_checker
and security.token_storage
.
Since this is a 100% backwards compatible change, you don't have to update the code of your applications. However, in case you want to do it, the changes are subtle:
1 2 3 4 5 6 7 8 9
// Symfony 2.5
$user = $this->get('security.context')->getToken()->getUser();
// Symfony 2.6
$user = $this->get('security.token_storage')->getToken()->getUser();
// Symfony 2.5
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) { ... }
// Symfony 2.6
if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) { ... }
As an added bonus of this change, the constants related to security are now shorter and much easier to remember:
1 2 3 4 5 6 7
// Symfony 2.5
use Symfony\Component\Security\Core\SecurityContextInterface;
if ($security->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { ... }
// Symfony 2.6
use Symfony\Component\Security\Core\Security;
if ($security->has(Security::AUTHENTICATION_ERROR)) { ... }
Lastly, this change also deprecates the app.security
global variable for Twig
templates. You should use instead the app.user
global variable and the
is_granted()
function.
New service to simplify password encoding
As a result of the DX proposal #11299, Symfony 2.6 will introduce a new
security.password_encoder
service to simplify password encoding:
1 2 3 4 5 6 7 8 9 10
// Symfony 2.5
$user = new Acme\UserBundle\Entity\User();
$factory = $this->container->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword($plainTextPassword, $user->getSalt());
// Symfony 2.6
$user = new Acme\UserBundle\Entity\User();
$encoder = $this->container->get('security.password_encoder');
$password = $encoder->encodePassword($user, $plainTextPassword);
Added a REMOTE_USER based listener to security firewalls
Several Apache security modules (auth_kerb
, auth_cas
, etc.) provide the
username
via an environment variable called REMOTE_USER
. For that reason,
Symfony 2.6 will include a new authentication listener based on this variable.
To use it in your application, simply define a firewall of the new remote_user
type in your security configuration:
1 2 3 4 5 6 7
# app/config/security.yml
security:
firewalls:
secured_area:
pattern: ^/
remote_user:
provider: your_user_provider
Added a security error helper
Customizing a login form in Symfony applications is pretty simple, but too verbose:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// Symfony 2.5
public function loginAction(Request $request)
{
$session = $request->getSession();
if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(
SecurityContextInterface::AUTHENTICATION_ERROR
);
} elseif (null !== $session && $session->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
$error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
$session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
} else {
$error = '';
}
$lastUsername = (null === $session) ? '' : $session->get(SecurityContextInterface::LAST_USERNAME);
return $this->render(
'AcmeSecurityBundle:Security:login.html.twig',
array(
'last_username' => $lastUsername,
'error' => $error,
)
);
}
As a result of the DX proposal #11147 Symfony 2.6 will include a new helper to drastically reduce the code used in the login form actions:
1 2 3 4 5 6 7 8 9 10
// Symfony 2.6
public function loginAction()
{
$helper = $this->get('security.authentication_utils');
return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
'last_username' => $helper->getLastUsername(),
'error' => $helper->getLastAuthenticationError(),
));
}
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
http://symfony.com/blog/new-in-symfony-2-6-new-shortcut-methods-for-controllers