Last active
February 7, 2017 21:37
-
-
Save tarlepp/0e2c779695b2aa96271c to your computer and use it in GitHub Desktop.
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 App\Listeners; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
use Symfony\Component\HttpKernel\Event\GetResponseEvent; | |
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; | |
use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
use Symfony\Component\Security\Core\Exception\AccessDeniedException; | |
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; | |
class AjaxAuthenticationListener | |
{ | |
/** | |
* Handles security related exceptions. | |
* | |
* @param GetResponseForExceptionEvent $event An GetResponseForExceptionEvent instance | |
*/ | |
public function onCoreException(GetResponseForExceptionEvent $event) | |
{ | |
$exception = $event->getException(); | |
$request = $event->getRequest(); | |
// It never hits here | |
if ($request->isXmlHttpRequest()) { | |
if ($exception instanceof AuthenticationException || $exception instanceof AccessDeniedException || $exception instanceof AuthenticationCredentialsNotFoundException) { | |
$responseData = array('status' => 401, 'msg' => 'User Not Authenticated'); | |
$response = new JsonResponse(); | |
$response->setData($responseData); | |
$response->setStatusCode($responseData['status']); | |
$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
[2016-02-11 21:45:44] myapp.INFO: Populated the TokenStorage with an anonymous Token. [] [] | |
[2016-02-11 21:45:44] myapp.INFO: > POST /backend/auth/login [] [] | |
[2016-02-11 21:45:44] myapp.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\UsernameNotFoundException(code: 0): User 'admdin' not found. at /home/wunder/projects/backend-silex/src/App/Providers/UserProvider.php:66)"} [] | |
[2016-02-11 21:45:44] myapp.DEBUG: Calling Authentication entry point. [] [] | |
[2016-02-11 21:45:44] myapp.INFO: < 302 http://wunder.sytes.net:6969/backend/login [] [] | |
[2016-02-11 21:45:44] myapp.ERROR: Symfony\Component\HttpKernel\Exception\NotFoundHttpException: No route found for "GET /login" (uncaught exception) at /home/wunder/projects/backend-silex/vendor/symfony/http-kernel/EventListener/RouterListener.php line 176 {"exception":"[object] (Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException(code: 0): No route found for \"GET /login\" at /home/wunder/projects/backend-silex/vendor/symfony/http-kernel/EventListener/RouterListener.php:176, Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException(code: 0): No routes found for \"/login\". at /home/wunder/projects/backend-silex/vendor/symfony/routing/Matcher/UrlMatcher.php:98)"} [] |
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 | |
/** | |
* /src/App/Application.php | |
* | |
* @author TLe, Tarmo Leppänen <[email protected]> | |
*/ | |
namespace App; | |
// Silex application | |
use App\Components\Swagger\SwaggerServiceProvider; | |
use App\Listeners\AjaxAuthenticationListener; | |
use App\Providers\SecurityServiceProvider as ApplicationSecurityServiceProvider; | |
use Silex\Application as SilexApplication; | |
// Silex specified providers | |
use Silex\Provider\DoctrineServiceProvider; | |
use Silex\Provider\MonologServiceProvider; | |
use Silex\Provider\SecurityJWTServiceProvider; | |
use Silex\Provider\SecurityServiceProvider; | |
use Silex\Provider\ValidatorServiceProvider; | |
// 3rd party providers | |
use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider; | |
use JDesrosiers\Silex\Provider\CorsServiceProvider; | |
use Sorien\Provider\PimpleDumpProvider; | |
use M1\Vars\Provider\Silex\VarsServiceProvider; | |
// Application specified providers | |
use App\Providers\UserProvider; | |
use App\Services\Loader; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; | |
/** | |
* Class Application | |
* | |
* Main application class that is used to run application. Class bootstraps application all providers, mount routes, | |
* etc. | |
* | |
* @category Core | |
* @package App | |
* @author TLe, Tarmo Leppänen <[email protected]> | |
*/ | |
class Application extends SilexApplication | |
{ | |
/** | |
* Project root directory, determined via this file | |
* | |
* @var string | |
*/ | |
private $rootDir; | |
/** | |
* Current environment which is used to run application. | |
* | |
* @var string | |
*/ | |
private $env; | |
/** | |
* Application constructor. | |
* | |
* @param string $env | |
*/ | |
public function __construct($env) | |
{ | |
// Set private vars | |
$this->rootDir = __DIR__ . '/../../'; | |
$this->env = $env; | |
// Construct Silex application | |
parent::__construct(); | |
// Create application configuration | |
$this->applicationConfig(); | |
// Register all necessary providers | |
$this->applicationRegister(); | |
// Configure application firewall | |
$this->applicationFirewall(); | |
// Load services | |
$this->loadServices(); | |
// Attach application mount points | |
$this->applicationMount(); | |
// Attach CORS to application | |
$this->after($this['cors']); | |
} | |
/** | |
* Getter method for 'rootDir' property. | |
* | |
* @return string | |
*/ | |
public function getRootDir() | |
{ | |
return $this->rootDir; | |
} | |
/** | |
* Getter method for 'env' property. | |
* | |
* @return string | |
*/ | |
public function getEnv() | |
{ | |
return $this->env; | |
} | |
/** | |
* Application configuration. | |
* | |
* @return void | |
*/ | |
private function applicationConfig() | |
{ | |
// Register configuration provider | |
$this->register( | |
new VarsServiceProvider($this->rootDir . 'resources/config/' . $this->env . '/config.yml'), | |
[ | |
'vars.options' => [ | |
'cache' => true, | |
'cache_path' => $this->rootDir . 'var', | |
'cache_expire' => $this->env === 'dev' ? 0 : 0, | |
'replacements' => [ | |
'rootDir' => $this->rootDir, | |
'env' => $this->env, | |
], | |
], | |
] | |
); | |
// Set application level values | |
$this['debug'] = $this['vars']->get('debug'); | |
$this['security.jwt'] = $this['vars']->get('security.jwt'); | |
$this['pimpledump.output_dir'] = $this['vars']->get('pimpledump.output_dir'); | |
$this['services'] = $this['vars']->get('services'); | |
return; | |
} | |
/** | |
* Method to register all specified providers for application. | |
* | |
* @return void | |
*/ | |
private function applicationRegister() | |
{ | |
$this['dispatcher']->addListener("kernel.exception", function(GetResponseForExceptionEvent $event) { | |
if ( | |
($event->getException()->getCode() == '403') || | |
($event->getException()->getCode() == '404') | |
) { | |
$request = $event->getRequest(); | |
if ($request->isXmlHttpRequest()) { | |
$event->setResponse(new Response("Access Denied", 403)); | |
} | |
} | |
}); | |
// Register all providers for application | |
$this->register(new ValidatorServiceProvider()); | |
$this->register(new SecurityServiceProvider()); | |
$this->register(new ApplicationSecurityServiceProvider()); | |
$this->register(new SecurityJWTServiceProvider()); | |
$this->register(new PimpleDumpProvider()); | |
$this->register(new MonologServiceProvider(), $this['vars']->get('monolog')); | |
$this->register(new DoctrineServiceProvider(), $this['vars']->get('database')); | |
$this->register(new DoctrineOrmServiceProvider(), $this['vars']->get('orm')); | |
$this->register(new CorsServiceProvider(), $this['vars']->get('cors')); | |
$this->register(new SwaggerServiceProvider(), $this['vars']->get('swagger')); | |
} | |
/** | |
* Method to setup application firewall. | |
* | |
* @see http://silex.sensiolabs.org/doc/providers/security.html | |
* | |
* @return array | |
*/ | |
private function applicationFirewall() | |
{ | |
$entityManager = $this['orm.em']; | |
$app = $this; | |
// Set provider for application users | |
$this['users'] = function() use ($app, $entityManager) { | |
return new UserProvider($entityManager); | |
}; | |
// Security Firewalls configuration | |
$this['security.firewalls'] = [ | |
// Root route | |
'root' => [ | |
'pattern' => '^/$', | |
'anonymous' => true, | |
], | |
// Login route | |
'login' => [ | |
'pattern' => '^/auth/login$', | |
'anonymous' => true, | |
], | |
// Pimple dump | |
'pimpleDump' => [ | |
'pattern' => '^/_dump$', | |
'anonymous' => true, | |
], | |
// CORS preflight requests | |
'cors-preflight' => array( | |
'pattern' => $this['cors_preflight_request_matcher'], | |
), | |
// API docs are also anonymous | |
'docs' => [ | |
'pattern' => '^/api', | |
'anonymous' => true, | |
], | |
// And all other routes | |
'secured' => [ | |
'pattern' => '^.*$', | |
'users' => $this['users'], | |
'jwt' => [ | |
'use_forward' => true, | |
'require_previous_session' => false, | |
'stateless' => true, | |
], | |
], | |
]; | |
} | |
/** | |
* Method to attach main mount point to be handled via ControllerProvider. | |
* | |
* @return void | |
*/ | |
private function applicationMount() | |
{ | |
// Register all application routes | |
$this->mount('', new ControllerProvider()); | |
} | |
/** | |
* Load shared services. | |
* | |
* @return void | |
*/ | |
private function loadServices() | |
{ | |
$loader = new Loader($this); | |
$loader->bindServicesIntoContainer(); | |
} | |
} |
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
var_dump($this['services']); | |
array(1) { | |
["ajax.listener"]=> | |
array(2) { | |
["class"]=> | |
string(39) "App\Listeners\AjaxAuthenticationListener" | |
["tags"]=> | |
array(1) { | |
[0]=> | |
array(4) { | |
["name"]=> | |
string(21) "kernel.event_listener" | |
["event"]=> | |
string(16) "kernel.exception" | |
["method"]=> | |
string(15) "onCoreException" | |
["priority"]=> | |
int(1000) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment