love and loss: a symfony security play

Post on 10-May-2015

5.983 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

The security component tackles the complex problems of authentication and authorization by spreading concerns across a number of single responsibility objects. This is a flexible design, but difficult for beginners to navigate. This presentation will bring the security component to life for us all to understand! Join us to see some of your favorite members of the Symfony community perform the security component in a series of scenes, interspliced with some technical descriptions of what's going on.

TRANSCRIPT

Love & LossA Symfony Security Play

brewcycleportland.com

@kriswallsmith

assetic

Buzz

Spork

“…the current implementation of the Security Component is … not easily accessible”

http://www.testically.org/2011/03/14/why-i-gave-up-on-the-symfony2-security-component/

“I would rather see Symfony2 postponed again or the Security Component removed …

I don’t think it is even near of being usable to the community outside the core.”

http://www.testically.org/2011/03/14/why-i-gave-up-on-the-symfony2-security-component/

“The past few days I have really be struggling with the Symfony2 security component. It is the most complex component of

Symfony2 if you ask me!”

http://blog.vandenbrand.org/2012/06/19/symfony2-authentication-provider-authenticate-against-webservice/

“(I’m) wondering if I should just work around rather than work with the framework”

https://groups.google.com/forum/#!msg/symfony2/AZpgbEk4Src/73P99zOmq2YJ

Enhance yourPHPfun!

http://curiouscomedy.org

HttpKernel

kernel.exception

kernel.request kernel.terminatekernel.controller kernel.view kernel.response

kernel.request kernel.controller kernel.view kernel.response kernel.terminate

kernel.exception

HttpKernel

kernel.request kernel.controller kernel.view kernel.response kernel.terminate

kernel.exception

HttpKernel

HttpKernelGet the response and get out

kernel.request

Routeretc…

Firewall

FirewallJust another listener

class YesFirewall{ public function handle($event) { // always say yes }}

use Symfony\Component\HttpFoundation\Response;

class NoFirewall{ public function handle($event) { // always say no $event->setResponse( new Response('go away', 401) ); }}

use Symfony\Component\HttpFoundation\Response;

class PickyFirewall{ public function handle($event) { $request = $event->getRequest(); $user = $request->headers->get('PHP_AUTH_USER');

// only names that start with "Q" if ('Q' == $user[0]) return;

$event->setResponse(new Response('go away', 401)); }}

Security ListenersThe firewall’s henchmen

Firewall

Listeners

kernel.request

class Firewall{ public $listeners = array();

public function handle($event) { foreach ($this->listeners as $listener) { $listener->handle($event);

if ($event->hasResponse()) return; } }}

class YesListener{ public function handle($event) { // always say yes }}

use Symfony\Component\HttpFoundation\Response;

class NoListener{ public function handle($event) { // always say no $event->setResponse( new Response('go away', 401) ); }}

use Symfony\Component\HttpFoundation\Response;

class PickyListener{ public function handle($event) { $request = $event->getRequest(); $user = $request->headers->get('PHP_AUTH_USER');

// only names that start with "Q" if ('Q' == $user[0]) return;

$event->setResponse(new Response('go away', 401)); }}

AuthenticationAre you who you say you are?

AuthorizationAre you allowed to ____?

TokensThe Language of Security

Authentication ListenersMap from request to token

Request

Response (?) Token

CoreHTTP

AuthenticationListener A

AuthenticationListener B

AuthenticationManager

Firewall

class AuthenticationListener{ public $authMan, $context;

public function handle($e) { $r = $e->getRequest(); $u = $r->headers->get('PHP_AUTH_USER');

$t = new AnonToken($u); $t = $this->authMan->authenticate($t);

$this->context->setToken($t); }}

class AuthenticationManager{ public function authenticate($t) { // always say no }}

class AuthenticationManager{ public function authenticate($t) { // always say yes return new AuthToken($t->getUser()); }}

class AuthenticationManager{ public function authenticate($t) { $u = $t->getUser(); // only names that start with "Q" if ('Q' == $u[0]) { return new AuthToken($u); } }}

Authentication ManagerResponsible for authenticating

the token

Authentication ProvidersDo the actual authentication work

UserProviders

AuthenticationProviders

AuthenticationListener A

AuthenticationListener B

AuthenticationManager

User ProvidersAccess the repository of users

class AuthenticationManager{ public $providers = array();

public function authenticate($t) { foreach ($this->providers as $p) { if ($p->supports($t)) { return $p->authenticate($t); } } }}

class AuthenticationProvider{ public $up;

public function authenticate($t) { $u = $t->getUser(); $u = $this->up->loadUserByUsername($u);

if ($u) return new AuthToken($u); }}

class UserProvider{ public $repo;

public function loadUserByUsername($u) { return ($this->repo->find(array( 'username' => $u, ))); }}

Authentication

Authentication Listeners

• Map client data from request to token

• Pass token to authentication manager

• Update state of security context

Authentication Manager

• Responsible for authenticating the token

• Calls the appropriate authentication provider

• Handles exceptions

Authentication Providers

• Performs authentication using client data in the token

• Marks the token as authenticated

• Attaches the user object to the token

User Providers

• Retrieves the user from the database

Authorization

class AuthorizationListener{ public function handle($e) { // always say yes }}

use Symfony\Component\HttpFoundation\Response;

class AuthorizationListener{ public function handle($e) { // always say no $e->setResponse( new Response('go away', 403) ); }}

Access MapLooks at a request and determines

token requirements

Access Decision ManagerThe gatekeeper

VotersDecisionManager

Listener Map

use Symfony\Component\HttpFoundation\Response;

class AccessListener{ public $context, $map, $decider;

public function handle($e) { $r = $e->getRequest(); $t = $this->context->getToken();

$reqs = $this->map->getRequirements($r);

if (!$this->decider->decide($t, $reqs)) { $e->setResponse( new Response('go away', 403) ); } }}

class AccessMap{ public function getRequirements($r) { $path = $r->getPathInfo(); if (0 === strpos($path, '/admin')) { return array('ADMIN'); } }}

class AccessDecisionManager{ public $voters;

public function decide($t, $reqs) { foreach ($this->voters as $v) { if ($v->vote($t, null, $reqs)) { return true; } }

return false; }}

class AccessVoter{ public function vote($t, $obj, $reqs) { foreach ($reqs as $req) { if (!$t->hasAttribute($req)) { return false; } }

return true; }}

Authorization

Extension Points

The firewall has many listeners

The authentication manager has many authentication providers

Which MAY rely onuser providers

The access decision manager has many voters

Authenticated

Roles

ACL

Questions?

is hiring

“Horrible”“Worst talk ever”

“Go back to high school”

https://joind.in/8665

top related