cystbearErlanger
Symfony expert
MongoDB adept
OSS doerhttps://twitter.com/1cdecoderhttps://github.com/cystbearhttp://trinity.ck.ua/
security.ymlsecurity: firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: pattern: ^/ form_login: login_path: /login check_path: /login_check provider: fos_userbundle logout: true anonymous: true
access_control: - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/user, role: ROLE_USER } - { path: ^/admin/, role: ROLE_ADMIN }
http://www.xml.com/pub/a/2003/12/17/dive.htmlhttp://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
Token<?phpnamespace AppBundle\Security\Authentication\Token;use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
class WsseUserToken extends AbstractToken{ public $created; public $digest; public $nonce; public function __construct(array $roles = array()) { parent::__construct($roles); // If the user has roles, consider it authenticated $this->setAuthenticated(count($roles) > 0); } public function getCredentials() { return ''; }}
Listener<?php
namespace AppBundle\Security\Firewall;
use AppBundle\Security\Authentication\Token\WsseUserToken;
class WsseListener implements ListenerInterface
{
protected $tokenStorage;
protected $authenticationManager;
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$wsseRegex = '/UsernameToken Username="([^"]+)", PasswordDigest="([^"]+)", Nonce="([^"]+)", Created="([^"]+)"/';
if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches)) {
return;
}
$token = new WsseUserToken(); $token->setUser($matches[1]); ...
try {
$authToken = $this->authenticationManager->authenticate($token);
$this->tokenStorage->setToken($authToken);
return;
} catch (AuthenticationException $failed) { ... }
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$event->setResponse($response);
}
}
Authentication Manager<?php
namespace AppBundle\Security\Authentication\Provider;
use AppBundle\Security\Authentication\Token\WsseUserToken;
class WsseProvider implements AuthenticationProviderInterface
{
private $userProvider;
public function authenticate(TokenInterface $token)
{
$user = $this->userProvider->loadUserByUsername($token->getUsername());
if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) {
$authenticatedToken = new WsseUserToken($user->getRoles());
$authenticatedToken->setUser($user);
return $authenticatedToken;
}
throw new AuthenticationException('The WSSE authentication failed.');
}
protected function validateDigest($digest, $nonce, $created, $secret)
{ ... }
public function supports(TokenInterface $token)
{
return $token instanceof WsseUserToken;
}
}
Factory<?php
namespace AppBundle\DependencyInjection\Security\Factory;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
class WsseFactory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$providerId = 'security.authentication.provider.wsse.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('wsse.security.authentication.provider'))
->replaceArgument(0, new Reference($userProvider))
;
$listenerId = 'security.authentication.listener.wsse.'.$id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('wsse.security.authentication.listener'));
return array($providerId, $listenerId, $defaultEntryPoint);
}
public function getPosition()
{ return 'pre_auth'; }
public function getKey()
{ return 'wsse'; }
public function addConfiguration(NodeDefinition $node)
{
}
}
ACE
http://symfony.com/doc/current/cookbook/security/acl.html
Voters
http://symfony.com/doc/current/cookbook/security/voters.htmlhttps://www.youtube.com/watch?v=e7HfW4TgnUY
Voter (1)<?php
namespace AppBundle\Security;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class PostVoter extends Voter
{
const VIEW = 'view';
const EDIT = 'edit';
protected function supports($attribute, $subject)
{
if (!in_array($attribute, array(self::VIEW, self::EDIT))) { return false; }
if (!$subject instanceof Post) { return false; }
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) { return false; }
$post = $subject;
switch($attribute) {
case self::VIEW: return $this->canView($post, $user);
case self::EDIT: return $this->canEdit($post, $user);
}
throw new \LogicException('This code should not be reached!');
}
}
Voter (2)<?php
private function canView(Post $post, User $user)
{
if ($this->canEdit($post, $user)) { return true; }
return !$post->isPrivate();
}
private function canEdit(Post $post, User $user)
{
return $user === $post->getOwner();
}
}
Top Related