• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Instant ACLs with Zend Framework 2
 

Instant ACLs with Zend Framework 2

on

  • 6,428 views

Slides of my Zend Framework Day 2014 presentation in Turin (Italy) about ZF2 authentication and authorization.

Slides of my Zend Framework Day 2014 presentation in Turin (Italy) about ZF2 authentication and authorization.

Statistics

Views

Total Views
6,428
Views on SlideShare
6,289
Embed Views
139

Actions

Likes
7
Downloads
64
Comments
0

3 Embeds 139

http://www.scoop.it 72
http://www.slideee.com 39
https://twitter.com 28

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Instant ACLs with Zend Framework 2 Instant ACLs with Zend Framework 2 Presentation Transcript

    • Instant ACLs with Zend Framework 2 Zend Framework Day – Turin, Italy – 07/02/2014
    • @stefanovalle
    • http://www.mvlabs.it/
    • http://friuli.grusp.org/
    • AUTHENTICATION AUTHORIZATION 5
    • Two step process
    • Two step process WHO WHAT
    • Two step process WHO Authentication “a process that ensures and confirms a user’s identity” WHAT Definitions from http://www.techopedia.com
    • Two step process WHO WHAT Authentication “a process that ensures and confirms a user’s identity” Authorization “a security mechanism used to determine user/client privileges or access levels related to system resources” Definitions from http://www.techopedia.com
    • 11
    • In ZF2 WHO Zend/Authentication
    • In ZF2 WHO Zend/Authentication Authenticate against: • DB table • LDAP • HTTP • And more…
    • In ZF2 WHAT Zend/Permissions/Acl Zend/Permissions/Rbac
    • In ZF2 WHAT Zend/Permissions/Acl Zend/Permissions/Rbac Role Permission Identity Resource
    • SEEMS TOUGH…
    • JUST AS IT SHOULD!
    • CONSEQUENCES COULD BE UNDERESTIMATED
    • How does ZF2 help? 19
    • ‘NUFF TALK. TIME FOR ACTION…
    • We need to add/edit conferences through a restricted area 1ST NEED
    • THE ADMINISTRATOR NEEDS TO BE RECOGNIZED
    • THE ADMINISTRATOR NEEDS TO BE RECOGNIZED IDENTIFIED
    • HEAD TO OFFICIAL MODULES’ WEBSITE
    • OH, LOOK WHAT WE JUST GOT!
    • Installing and enabling ZfcUser // composer.json "require": { "zf-commons/zfc-user-doctrine-orm": "0.1.*" } 28
    • Installing and enabling ZfcUser // composer.json "require": { "zf-commons/zfc-user-doctrine-orm": "0.1.*" } let’s suppose we use the Doctrine ORM 29
    • Installing and enabling ZfcUser // composer.json "require": { "zf-commons/zfc-user-doctrine-orm": "0.1.*" } // config/application.config.php <?php return array( 'modules' => array( // ... 'ZfcBase', 'ZfcUser', 'ZfcUserDoctrineORM', ), ); 30
    • Back to our user… 31
    • How shall we represent him?
    • We need a class class Systemuser { private $id; private $name; private $city; private $birthday; private $username; private $password; }
    • With some mandatory fields class Systemuser { private $id; private $name; private $city; private $birthday; private $username; private $password; }
    • Implementing an interface class Systemuser implements ZfcUserEntityUserInterface { private $id; private $name; private $city; private $birthday; private $username; private $password; }
    • Let’s configure ZfcUser // config/autoload/zfcuser.global.php /** ZfcUser Configuration */ $settings = array( /** User Model Entity Class */ 'user_entity_class' => 'ApplicationEntitySystemuser', /** Start configuration for ZfcUserDoctrineORM */ 'enable_default_entities' => false, ); 36
    • Yay, here’s our working login form! 37
    • Yay, here’s our working login form! Available at: http://myaddress/user/login 38
    • Yay, it works! 39
    • ZfcUser also allows to: • • • • • 40 Customize login form Customize User entity fields Quickly implement a registration form Interact with either Zend/DB or Doctrine out of the box Do much more stuff…
    • ZfcUser also allows to: • • • • • 41 Customize login form Customize User entity fields Quickly implement a registration form Interact with either Zend/DB or Doctrine out of the box Do much more stuff…
    • Remember the two steps? WHO WHAT
    • Remember the two steps? WHO WHAT
    • We need an admin panel! 44
    • We need an admin panel! Welcome ZfcAdmin! provides a ready to use /admin route 45
    • hubme.in has an admin panel!
    • hubme.in has an admin panel!
    • Are we done yet? 48
    • What if a malicious user…
    • What if a malicious user…
    • What if a malicious user… …hits this url: http://myawesomewebsite/admin/conferences
    • What if a malicious user… …hits this url: http://myawesomewebsite/admin/conferences accessible to everyone!
    • What if a malicious user… …hits this url: http://myawesomewebsite/admin/conferences nothing’s protecting our private area
    • What if a malicious user… …hits this url: http://myawesomewebsite/admin/conferences nothing’s protecting our private area Login form could be bypassed!
    • No worries! /* * On each action */ <?php public function indexAction() { if (!$this->zfcUserAuthentication()->hasIdentity()) { return $this->redirect()->toRoute('home'); } } 55
    • No worries! /* * On each action */ <?php public function indexAction() { if (!$this->zfcUserAuthentication()->hasIdentity()) { return $this->redirect()->toRoute('home'); } } 56 in EACH action of EACH controller
    • WHAAAT?
    • IN EACH ACTION???
    • SOMEONE HELP US!
    • ZENDPERMISSIONSACL
    • Remember? There were two steps… WHO WHAT
    • Using Zend/Permissions/Acl <?php use ZendPermissionsAclAcl; use ZendPermissionsAclRoleGenericRole as Role; use ZendPermissionsAclResourceGenericResource as Resource; $acl = new Acl(); $acl->addRole(new Role('guest')) ->addRole(new Role('admin')); $acl->addResource(new $acl->addResource(new $acl->addResource(new $acl->addResource(new $acl->allow('guest', $acl->allow('admin', $acl->allow('admin', $acl->allow('admin', 62 Resource('someResource')); Resource('adminarea')); Resource('adminconferencearea')); Resource('adminsettingsarea')); 'someResource'); 'adminarea'); 'adminconferencearea '); 'adminsettingsarea ');
    • Welcome BjyAuthorize! … a facade for ZendPermissionsAcl that will ease its usage with modules and applications … From https://github.com/bjyoungblood/BjyAuthorize 63
    • Welcome BjyAuthorize! … a facade for ZendPermissionsAcl that will ease its usage with modules and applications … From https://github.com/bjyoungblood/BjyAuthorize 64
    • OUR EASIER WAY
    • How does it work? 66
    • Standard ZendMvc app workflow From https://github.com/bjyoungblood/BjyAuthorize 67
    • With BjyAuthorize enabled From https://github.com/bjyoungblood/BjyAuthorize 68
    • With BjyAuthorize enabled From https://github.com/bjyoungblood/BjyAuthorize 69
    • With BjyAuthorize enabled From https://github.com/bjyoungblood/BjyAuthorize 70
    • With BjyAuthorize enabled + control over resources From https://github.com/bjyoungblood/BjyAuthorize 71
    • Installing and enabling BjyAuthorize // composer.json "require": { "bjyoungblood/bjy-authorize": "1.4.*" } // config/application.config.php <?php return array( 'modules' => array( // ... 'BjyAuthorize', ), ); 72
    • Configuring BjyAuthorize // config/autoload/bjyauthorize.global return array( 'bjyauthorize' => array( 'default_role' => 'guest', 'identity_provider' => 'BjyAuthorizeProviderIdentityAuthenticationIdentityProvider', 'role_providers' => array( 'BjyAuthorizeProviderRoleConfig' => array( 'guest' => array(), 'admin' => array(), ), ), ), ); 73
    • Configuring BjyAuthorize // config/autoload/bjyauthorize.global return array( 'bjyauthorize' => array( A new concept: the Role 'default_role' => 'guest', 'identity_provider' => 'BjyAuthorizeProviderIdentityAuthenticationIdentityProvider', 'role_providers' => array( 'BjyAuthorizeProviderRoleConfig' => array( 'guest' => array(), 'admin' => array(), ), ), ), ); 74
    • Guards on routes http://myawesomewebsite/ Allowed to all users 75
    • Guards on routes http://myawesomewebsite/ Allowed to all users http://myawesomewebsite/admin/... Restricted area! For admins only 76
    • Guards on controller actions class ConferencesController { public function listAction() { // code... } public function manageAction() { // code... } } 77
    • Guards on controller actions class ConferencesController { public function listAction() { // code... } Allowed public function manageAction() { // code... } } 78 to all users
    • Guards on controller actions class ConferencesController { public function listAction() { // code... } Allowed to all users public function manageAction() { // code... } } 79 Restricted area! For admins only
    • Guards on controller actions array( 'controller' => 'ZfcAdminControllerAdminController', 'roles' => array('admin') ) 80
    • Where should guards be placed? 81
    • Inside each module configuration // module/Conferences/config/module.config.php return array( 'bjyauthorize' => array( 'guards' => array( 'BjyAuthorizeGuardController' => array( //... ), ), ), 82
    • Inside each module configuration // module/Conferences/config/module.config.php return array( 'bjyauthorize' => array( Taking advantage of ZF2 configuration merge 'BjyAuthorizeGuardController' => array( 'guards' => array( //... ), ), ), 83
    • It works!
    • It works! User could be redirected to whatever url we want
    • Dude, forgot to tell ya! …we got 2 fellas! 2ND NEED
    • Two different roles The reader 87
    • Two different roles The reader 88
    • Two different roles The reader 89 The editor
    • Two different roles Can only view conference info The reader 90 Can view conferences + create, edit and delete info The editor
    • What we want Only editor should see these icons
    • Until now… 'bjyauthorize' => array( // ... 'role_providers' => array( 'BjyAuthorizeProviderRoleConfig' => array( 'guest' => array(), 'admin' => array(), ), ), ) Static role list 93
    • Until now… 'bjyauthorize' => array( // ... 'role_providers' => array( 'BjyAuthorizeProviderRoleConfig' => array( 'guest' => array(), 'admin' => array(), ), ), ) More flexibility wouldn’t hurt… 94
    • BjyAuthorize config changes // config/autoload/bjyauthorize.global return array( 'bjyauthorize' => array( 'role_providers' => array( 'BjyAuthorizeProviderRoleObjectRepositoryProvider' => array( 'role_entity_class' => 'ApplicationEntityRole', 'object_manager' => 'doctrine.entity_manager.orm_default', ), ), ), ); From array to class (persisted on db) 95
    • Let’s map the actions
    • New concept: the Resource
    • something
    • something upon which someone
    • something upon which someone could perform an action
    • ENTITY IDENTITY / ROLE PRIVILEGE
    • On BjyAuthorize… 'resource_providers' => array( 'BjyAuthorizeProviderResourceConfig' => array( 'Conference' => array(), ), ), 'rule_providers' => array( 'BjyAuthorizeProviderRuleConfig' => array( 'allow' => array( // allow editors to edit conferences array(array('editor'), 'Conference', array('edit')), ), ), 102
    • On views… //Conferences/view/…/index.phtml <?php if ($this->isAllowed($event, 'edit')) { ?> <a href="someurl">Remove</a><br /> <a href="someurl">Edit</a> <?php } ?> 103
    • Views, routes and controllers are safe 104
    • Views, routes and controllers are safe Is this enough? 105
    • Another controller, another action //Conferences/Controller/AnotherAdminController.php class AnotherAdminController extends AbstractActionController { public function someCrazyAction() { //... $this->conferenceService->updateConference($myConference); } } What prevents this? 106
    • 107 SERVICE CONTROLLER ROUTE Choose your protection level
    • Conference service //Conferences/Service/ConferenceService.php namespace ConferencesService; class ConferenceService { public function getConference($id) { ... } public function getConferenceList($someCriteria) { ... } public function updateConference($myConf) { ... } public function deleteConference($myConf) { ... } } 108
    • Conference service //Conferences/Service/ConferenceService.php namespace ConferencesService; class ConferenceService { public function getConference($id) { ... } public function getConferenceList($someCriteria) { ... } public function updateConference($myConf) { ... } public function deleteConference($myConf) { ... } } Only to allowed users! 109
    • Let’s inject the Authorize class //Conferences/Service/ConferenceServiceFactory.php namespace ConferencesService; class ConferenceServiceFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $serviceLocator) { //... $authorize = $serviceLocator->get('BjyAuthorizeServiceAuthorize'); return new ConferenceService(..., $authorize); } } 110
    • Updated conference service //Conferences/Service/ConferenceService.php namespace ConferencesService; class ConferenceService { //... public function updateConference($myConf) { if (!$this->authorize->isAllowed($myConf, 'edit')) { throw new UnAuthorizedException(); } // other code... } // the same for deleteConference method } 111
    • 112 SERVICE CONTROLLER ROUTE Now our service is secured
    • We’ll outsource the management of foreign conferences 3RD NEED
    • Based on their country
    • How database changes class Systemuser { //... private $country; } class Conference { //... private $country; } 116
    • Create an Assertion use ZendPermissionsAclAssertionAssertionInterface; class CheckUserCountry implements AssertionInterface { // ... public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { // ... } } 117
    • Create an Assertion use ZendPermissionsAclAssertionAssertionInterface; class CheckUserCountry implements AssertionInterface { // ... public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { return $resource->getCountry() == $this->loggedUser->getCountry(); } } 118
    • Create an Assertion use ZendPermissionsAclAssertionAssertionInterface; class CheckUserCountry implements AssertionInterface { // ... Injected through constructor public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { return $resource->getCountry() == $this->loggedUser->getCountry(); } } 119
    • Create an Assertion use ZendPermissionsAclAssertionAssertionInterface; class CheckUserCountry implements AssertionInterface { // ... public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { return $resource->getCountry() == $this->loggedUser->getCountry(); } } 120 1 LoC… AWESOME!!
    • Update rule with the new assertion 'rule_providers' => array( 'BjyAuthorizeProviderRuleConfig' => array( 'allow' => array( // role check through assertion array(array('editor'), 'Conference', array('edit'), 'assertion.CheckUserCountry'), ), ), 121
    • The reader 122
    • The reader The editor 123
    • In the same way we could: • • • 124 Restrict access to user owned onferences only or conferences owned by a group the user is belonging to …and much more!
    • Cool. How'bout the admin menu though? 4TH NEED
    • Navigation menu 126
    • Configure Zend/Navigation // module/Conferences/config/module.config.php return array( 'navigation' => array( 'admin' => array( 'conferences' => array( 'label' => 'Conferences', 'route' => 'zfcadmin/conferences', 'resource' => 'Conference', 'privilege' => 'view', ), ), ), ), ); 127
    • Configure Zend/Navigation // module/Settings/config/module.config.php return array( 'navigation' => array( 'admin' => array( 'settings' => array( 'label' => 'Settings', 'route' => 'zfcadmin/settings', 'resource' => 'Setting', 'privilege' => 'view', ), ), ), ), ); 128
    • How menu looks like for admins
    • How menu looks like for other users
    • FINAL NOTES
    • PLUGGABLE COMPONENTS
    • PLUGGABLE COMPONENTS CLEAN ARCHITECTURE
    • PLUGGABLE COMPONENTS CLEAN ARCHITECTURE COMPLEX ACL LOGIC IN A FEW MINUTES
    • Thank you for your attention! Stefano Valle @stefanovalle s.valle@mvassociati.it
    • Questions? Stefano Valle @stefanovalle s.valle@mvassociati.it
    • Photo Credits From Flickr: http://www.flickr.com/photos/cbpphotos/8652042987 http://www.flickr.com/photos/disa4ever/9409743179 http://www.flickr.com/photos/ben_salter/6169305845 http://www.flickr.com/photos/elzey/3481161467 http://www.flickr.com/photos/morris278/8022505933 A-Team members’ photos: http://5gta.com/gta-5-info/gta-5-the-a-team-similarities.html/ http://www.legendarytv.com/the_a-team/the_a-team_lance_legault.asp http://www.fanpop.com/clubs/the-a-team/images http://dwightschultz.freeforums.org/dwight-photo-s-t8.html http://docmanhattan.blogspot.it/2010/10/vita-mort-immortalita-e-miracoli-di-mr.html http://www.starsky-iom.com/forum/viewtopic.php?f=8&t=58 http://www.thea-teamonline.com/ And others form iStockPhoto 137