Created
March 19, 2014 20:57
-
-
Save Sorendil/9651061 to your computer and use it in GitHub Desktop.
Wsse install
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
imports: | |
- { resource: parameters.yml } | |
- { resource: security.yml } | |
# SonataAdmin configs | |
- { resource: @TheFirefliesSportBundle/Resources/config/admin.yml } | |
# Personal configs | |
- { resource: @TheFirefliesSportBundle/Resources/config/services.yml } | |
- { resource: @TheFirefliesUserBundle/Resources/config/services.yml } | |
# ........ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
security: | |
encoders: | |
Symfony\Component\Security\Core\User\User: plaintext | |
FOS\UserBundle\Model\UserInterface: sha512 | |
providers: | |
in_memory: | |
memory: | |
users: | |
user: { password: userpass, roles: [ 'ROLE_USER' ] } | |
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } | |
fos_userbundle: | |
id: fos_user.user_provider.username | |
firewalls: | |
dev: | |
pattern: ^/(_(profiler|wdt)|css|images|js)/ | |
security: false | |
login: | |
pattern: ^/demo/secured/login$ | |
security: false | |
secured_area: | |
pattern: ^/demo/secured/ | |
form_login: | |
check_path: _security_check | |
login_path: _demo_login | |
logout: | |
path: _demo_logout | |
target: _demo | |
#anonymous: ~ | |
#http_basic: | |
# realm: "Secured Demo Area" | |
main: | |
pattern: ^/ | |
form_login: | |
provider: fos_userbundle | |
csrf_provider: form.csrf_provider | |
logout: true | |
anonymous: true | |
wsse_secured: | |
pattern: ^/api/.* | |
stateless: true | |
wsse: true | |
anonymous : false | |
access_control: | |
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } | |
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: ^/admin/, role: ROLE_ADMIN } | |
role_hierarchy: | |
ROLE_ADMIN: | |
- ROLE_USER | |
- ROLE_CLUB_EDIT | |
- ROLE_CLUB_DELETE | |
- ROLE_TEAM_EDIT | |
- ROLE_TEAM_DELETE | |
ROLE_SUPER_ADMIN: | |
- ROLE_ADMIN | |
- ROLE_ALLOWED_TO_SWITCH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# src/TheFireflies/UserBundle/Resources/config/services.yml | |
services: | |
wsse.security.authentication.provider: | |
class: TheFireflies\UserBundle\Security\Authentication\Provider\WsseProvider | |
arguments: ['', %kernel.cache_dir%/security/nonces] | |
wsse.security.authentication.listener: | |
class: TheFireflies\UserBundle\Security\Firewall\WsseListener | |
arguments: [@security.context, @security.authentication.manager, @logger] | |
tags: | |
- { name: monolog.logger, channel: wsse } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace TheFireflies\UserBundle\DependencyInjection\Security\Factory; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\DependencyInjection\Reference; | |
use Symfony\Component\DependencyInjection\DefinitionDecorator; | |
use Symfony\Component\Config\Definition\Builder\NodeDefinition; | |
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; | |
echo "-FactoryProviderId:". $id . "-"; | |
$container | |
->setDefinition($providerId, new DefinitionDecorator('wsse.security.authentication.provider')) | |
->replaceArgument(0, new Reference($userProvider)) | |
; | |
echo "-FactoryProviderEtape2-"; | |
$listenerId = 'security.authentication.listener.wsse.'.$id; | |
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('wsse.security.authentication.listener')); | |
echo "-FactoryProviderEtape3-"; | |
return array($providerId, $listenerId, $defaultEntryPoint); | |
} | |
public function getPosition() | |
{ | |
return 'pre_auth'; | |
} | |
public function getKey() | |
{ | |
return 'wsse'; | |
} | |
public function addConfiguration(NodeDefinition $node) | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace TheFireflies\UserBundle\Security\Firewall; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpKernel\Event\GetResponseEvent; | |
use Symfony\Component\Security\Http\Firewall\ListenerInterface; | |
use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
use Symfony\Component\Security\Core\SecurityContextInterface; | |
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; | |
use Psr\Log\LoggerInterface; | |
use TheFireflies\UserBundle\Security\Authentication\Token\WsseUserToken; | |
class WsseListener implements ListenerInterface | |
{ | |
protected $securityContext; | |
protected $authenticationManager; | |
protected $logger; | |
public function __construct(SecurityContextInterface $securityContext, | |
AuthenticationManagerInterface $authenticationManager, | |
LoggerInterface $logger) | |
{ | |
$this->securityContext = $securityContext; | |
$this->authenticationManager = $authenticationManager; | |
$this->logger = $logger; | |
} | |
public function handle(GetResponseEvent $event) | |
{ | |
$request = $event->getRequest(); | |
echo "-ListenerEtape1-"; | |
$wsseRegex = '/UsernameToken Username="([^"]+)", PasswordDigest="([^"]+)", Nonce="([^"]+)", Created="([^"]+)"/'; | |
if (!$request->headers->has('x-wsse') | |
|| 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches)) { | |
echo "-ListenerEtape2-"; | |
return; | |
} | |
echo "-ListenerEtape3-"; | |
$token = new WsseUserToken(); | |
$token->setUser($matches[1]); | |
$token->digest = $matches[2]; | |
$token->nonce = $matches[3]; | |
$token->created = $matches[4]; | |
try { | |
$authToken = $this->authenticationManager->authenticate($token); | |
$this->securityContext->setToken($authToken); | |
return; | |
} catch (AuthenticationException $failed) { | |
// On log... | |
$failedMessage = 'WSSE Login failed for '.$token->getUsername().'. Why ? '.$failed->getMessage(); | |
$this->logger->err($failedMessage); | |
// To deny the authentication clear the token. This will redirect to the login page. | |
// $this->securityContext->setToken(null); | |
// return; | |
// Deny authentication with a '403 Forbidden' HTTP response | |
$response = new Response(); | |
$response->setStatusCode(403); | |
$response->setContent($failedMessage); | |
$event->setResponse($response); | |
return; | |
} | |
// By default deny authorization | |
$response = new Response(); | |
$response->setStatusCode(403); | |
$event->setResponse($response); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace TheFireflies\UserBundle\Security\Authentication\Provider; | |
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; | |
use Symfony\Component\Security\Core\User\UserProviderInterface; | |
use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
use Symfony\Component\Security\Core\Exception\NonceExpiredException; | |
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |
use THeFireflies\UserBundle\Security\Authentication\Token\WsseUserToken; | |
class WsseProvider implements AuthenticationProviderInterface | |
{ | |
private $userProvider; | |
private $cacheDir; | |
public function __construct(UserProviderInterface $userProvider, $cacheDir) | |
{ | |
$this->userProvider = $userProvider; | |
$this->cacheDir = $cacheDir; | |
} | |
public function authenticate(TokenInterface $token) | |
{ | |
$user = $this->userProvider->loadUserByUsername($token->getUsername()); | |
if(!$user){ | |
throw new AuthenticationException("Bad credentials... Did you forgot your username ?"); | |
} | |
echo "-ProviderEtape1-"; | |
if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) { | |
echo "-ProviderEtape2-"; | |
$authenticatedToken = new WsseUserToken($user->getRoles()); | |
$authenticatedToken->setUser($user); | |
return $authenticatedToken; | |
} | |
echo "-ProviderEtape3-"; | |
throw new AuthenticationException('The WSSE authentication failed.'); | |
} | |
protected function validateDigest($digest, $nonce, $created, $secret) | |
{ | |
// Check created time is not in the future | |
if (strtotime($created) > time()) { | |
throw new AuthenticationException("Back to the future..."); | |
} | |
// Expire le timestamp après 5 minutes | |
if (time() - strtotime($created) > 300) { | |
return false; | |
} | |
// Valide que le nonce est unique dans les 5 minutes | |
if (file_exists($this->cacheDir.'/'.$nonce) && file_get_contents($this->cacheDir.'/'.$nonce) + 300 > time()) { | |
throw new NonceExpiredException('Previously used nonce detected'); | |
} | |
file_put_contents($this->cacheDir.'/'.$nonce, time()); | |
// Valide le Secret | |
$expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true)); | |
if($digest !== $expected){ | |
throw new AuthenticationException("Bad credentials ! Digest is not as expected."); | |
} | |
return true; | |
} | |
public function supports(TokenInterface $token) | |
{ | |
return $token instanceof WsseUserToken; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace TheFireflies\UserBundle\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); | |
echo "Compte le nombre de roles : " . count($roles); | |
// Si l'utilisateur a des rôles, on le considère comme authentifié | |
$this->setAuthenticated(count($roles) > 0); | |
} | |
public function getCredentials() | |
{ | |
return ''; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment