├── .gitignore ├── .php_cs ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.properties ├── build.xml ├── composer.json ├── phpdoc.dist.xml ├── phpunit.xml.dist ├── src ├── Adapter │ └── Db │ │ └── PdoAdapter.php ├── Authenticator.php ├── IdentityInterface.php └── Middleware │ └── Authorization.php ├── tests ├── Adapter │ └── Db │ │ └── PdoAdapterTest.php ├── AuthenticatorTest.php ├── Middleware │ └── AuthorizationTest.php └── bootstrap.php └── travis.xml /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | composer.lock 3 | vendor/ 4 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in('src/') 7 | ->in('tests/'); 8 | 9 | return \Symfony\CS\Config\Config::create() 10 | ->setUsingCache(true) 11 | ->fixers([ 12 | '-psr0', // Because it causes such grief with the Tests namespace in the tests folder 13 | '-single_blank_line_before_namespace', 14 | '-pre_increment', 15 | '-concat_without_spaces', 16 | '-phpdoc_inline_tag', 17 | 'concat_with_spaces', 18 | 'ordered_use', 19 | ]) 20 | ->finder($finder); 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - '5.5' 5 | - '5.6' 6 | - '7.0' 7 | - hhvm 8 | - nightly 9 | 10 | before_script: 11 | - composer install --prefer-source 12 | 13 | script: phpunit -c travis.xml 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## Pull Requests 4 | 5 | 1. Create your own [fork](https://help.github.com/articles/fork-a-repo) of the repo 6 | 2. Create a new branch for each feature or improvement 7 | 3. Send a pull request from each feature branch to the **develop** branch 8 | 9 | It is very important to separate new features or improvements into separate 10 | feature branches, and to send a pull request for each branch. This allows me to 11 | review and pull in new features or improvements individually. 12 | 13 | ## Style Guide 14 | 15 | All pull requests must adhere to the [PSR-2 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md). 16 | 17 | ## Unit Testing 18 | 19 | All pull requests must be accompanied by passing unit tests and complete code 20 | coverage. This library uses PHPUnit for testing. 21 | 22 | [Learn about PHPUnit](https://github.com/sebastianbergmann/phpunit/) 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2016 Jeremy Kendall 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slim Auth [![Build Status](https://travis-ci.org/jeremykendall/slim-auth.png?branch=master)](https://travis-ci.org/jeremykendall/slim-auth) [![Coverage Status](https://coveralls.io/repos/jeremykendall/slim-auth/badge.png?branch=master)](https://coveralls.io/r/jeremykendall/slim-auth?branch=master) [![Dependencies Status](https://depending.in/jeremykendall/slim-auth.png)](http://depending.in/jeremykendall/slim-auth) 2 | 3 | Slim Auth is an authorization and authentication library for the [Slim Framework][1]. 4 | Authentication is provided by the Zend Framework [Zend\Authentication][2] 5 | component, and authorization by the Zend Framework [Zend\Permissions\Acl][3] component. 6 | 7 | ## Fair Warning: Documentation Mostly Complete 8 | 9 | Slim Auth is fully functional and production ready (I've used it in production 10 | in multiple projects), but this documentation is incomplete. (Current status of 11 | the documentation is ~90% complete.) 12 | 13 | If you're familiar with [Zend\Authentication][2] and [Zend\Permissions\Acl][3], you'll be able to implement the library without any trouble. Otherwise, you might want to wait for the docs to be completed (no ETA) or open a GitHub issue with any questions or problems you encounter. 14 | 15 | Caveat emptor and all that. 16 | 17 | ## Slim SessionCookie No Longer Recomended 18 | 19 | **TL;DR**: You *will* experience unexpected behavior if you use 20 | `Zend\Authentication\Storage\Session` as your auth storage and 21 | `Slim\Middleware\SessionCookie` to provide encrypted cookies when your Slim 22 | version is >= 2.6. 23 | 24 | Earlier versions of this documentation (and the [sample implementation][10]) 25 | demonstrated the use of Slim's [SessionCookie Middleware](http://docs.slimframework.com/#Cookie-Session-Store) as a way to handle session storage in concert with Zend Session. As of [Slim 2.6.0](https://github.com/slimphp/Slim/releases/tag/2.6.0), 26 | Zend Session and Slim's SessionCookie middleware no longer play well together, 27 | and I've opted for a Zend Session only approach. 28 | 29 | ## Requirements 30 | 31 | Slim Auth works with all versions of Slim 2 >= 2.4.2. Slim Auth has not been 32 | tested against the upcoming Slim 3 release. 33 | 34 | ## Example Implementation 35 | 36 | I've put together an example implementation to demonstrate the library in 37 | action. The example implementation can be found [here][10]. 38 | 39 | ## Installation 40 | 41 | Installation is provided via [Composer][11]. 42 | 43 | First, install Composer. 44 | 45 | ``` 46 | curl -s https://getcomposer.org/installer | php 47 | ``` 48 | 49 | Then install Slim Auth with the following Composer command. 50 | 51 | ``` 52 | composer require jeremykendall/slim-auth 53 | ``` 54 | 55 | Finally, add this line at the top of your application’s index.php file: 56 | 57 | ``` 58 | require 'vendor/autoload.php'; 59 | ``` 60 | 61 | ## Preparing Your App For Slim Auth 62 | 63 | ### Database 64 | 65 | Your database should have a user table, and that table must have a `role` 66 | column. The contents of the `role` column should be a string and correspond to 67 | the roles in your ACL. The table name and all other column names are up to you. 68 | 69 | Here's an example schema for a user table. If you don't already have a user 70 | table, feel free to use this one: 71 | 72 | ``` 73 | CREATE TABLE IF NOT EXISTS [users] ( 74 | [id] INTEGER NOT NULL PRIMARY KEY, 75 | [username] VARCHAR(50) NOT NULL, 76 | [role] VARCHAR(50) NOT NULL, 77 | [password] VARCHAR(255) NULL 78 | ); 79 | ``` 80 | 81 | ### ACL 82 | 83 | An Access Control List, or ACL, defines the set of rules that determines which group 84 | of users have access to which routes within your Slim application. Below is a very simple example ACL. Please pay special attention to the comments. 85 | 86 | *Please refer to the [Zend\Permissions\Acl documentation][3] for complete details on using the Zend Framework ACL component.* 87 | 88 | ``` 89 | namespace Example; 90 | 91 | use Zend\Permissions\Acl\Acl as ZendAcl; 92 | 93 | class Acl extends ZendAcl 94 | { 95 | public function __construct() 96 | { 97 | // APPLICATION ROLES 98 | $this->addRole('guest'); 99 | // member role "extends" guest, meaning the member role will get all of 100 | // the guest role permissions by default 101 | $this->addRole('member', 'guest'); 102 | $this->addRole('admin'); 103 | 104 | // APPLICATION RESOURCES 105 | // Application resources == Slim route patterns 106 | $this->addResource('/'); 107 | $this->addResource('/login'); 108 | $this->addResource('/logout'); 109 | $this->addResource('/member'); 110 | $this->addResource('/admin'); 111 | 112 | // APPLICATION PERMISSIONS 113 | // Now we allow or deny a role's access to resources. The third argument 114 | // is 'privilege'. We're using HTTP method as 'privilege'. 115 | $this->allow('guest', '/', 'GET'); 116 | $this->allow('guest', '/login', array('GET', 'POST')); 117 | $this->allow('guest', '/logout', 'GET'); 118 | 119 | $this->allow('member', '/member', 'GET'); 120 | 121 | // This allows admin access to everything 122 | $this->allow('admin'); 123 | } 124 | } 125 | ``` 126 | 127 | #### The Guest Role 128 | 129 | Please note the `guest` role. **You must use the name** `guest` **as the role 130 | assigned to unauthenticated users**. The other role names are yours to choose. 131 | 132 | #### Acl "Privileges" 133 | 134 | **IMPORTANT**: The third argument to `Acl::allow()`, 'privileges', is either a 135 | string or an array, and should be an HTTP verb or HTTP verbs respectively. By 136 | adding the third argument, you are restricting route access by HTTP method. If 137 | you do not provide an HTTP verb or verbs, you are allowing access to the 138 | specified route via *all* HTTP methods. **Be extremely vigilant here.** You 139 | wouldn't want to accidentally allow a 'guest' role access to an admin `DELETE` 140 | route simply because you forgot to explicitly deny the `DELETE` route. 141 | 142 | ## Configuring Slim Auth: Defaults 143 | 144 | Now that you have a user database table with a `role` column and an ACL, you're 145 | ready to configure Slim Auth and add it to your application. 146 | 147 | First, add `use` statements for the PasswordValidator (from the 148 | [Password Validator][9] library), the PDO adapter, and the Slim Auth Bootstrap. 149 | 150 | ``` 151 | use JeremyKendall\Password\PasswordValidator; 152 | use JeremyKendall\Slim\Auth\Adapter\Db\PdoAdapter; 153 | use JeremyKendall\Slim\Auth\Bootstrap; 154 | ``` 155 | 156 | Next, create your Slim application. 157 | 158 | ``` 159 | $app = new \Slim\Slim(); 160 | ``` 161 | 162 | ### Authentication Adapter 163 | 164 | From the Zend Authentication documentation: 165 | 166 | > `Zend\Authentication` adapters are used to authenticate against a particular 167 | > type of authentication service, such as LDAP, RDBMS, or file-based storage. 168 | 169 | Slim Auth provides an RDBMS authentication adapter for [PDO][12]. The constructor 170 | accepts five required arguments: 171 | 172 | * A `\PDO` instance 173 | * The name of the user table 174 | * The name of the identity, or username, column 175 | * The name of the credential, or password, column 176 | * An instance of `JeremyKendall\Password\PasswordValidator` 177 | 178 | ``` 179 | $db = new \PDO(); 180 | $adapter = new PdoAdapter( 181 | $db, 182 | , 183 | , 184 | , 185 | new PasswordValidator() 186 | ); 187 | ``` 188 | 189 | > **NOTE**: Please refer to the [Password Validator documentation][9] for more 190 | > information on the proper use of the library. If you choose not to use the 191 | > Password Validator library, you will need to create your own authentication 192 | > adapter. 193 | 194 | ### Putting it all Together 195 | 196 | Now it's time to instantiate your ACL and bootstrap Slim Auth. 197 | 198 | ``` 199 | $acl = new \Namespace\For\Your\Acl(); 200 | $authBootstrap = new Bootstrap($app, $adapter, $acl); 201 | $authBootstrap->bootstrap(); 202 | ``` 203 | 204 | ### Login Route 205 | 206 | You'll need a login route, of course, and it's important that you name your 207 | route `login` using Slim's [Route Names][4] feature. 208 | 209 | ``` 210 | $app->map('/login', function() {})->via('GET', 'POST')->name('login'); 211 | ``` 212 | 213 | This allows you to use whatever route pattern you like for your login route. 214 | Slim Auth will redirect users to the correct route using Slim's `urlFor()` 215 | [Route Helper][5]. 216 | 217 | Here's a sample login route: 218 | 219 | ``` 220 | // Login route MUST be named 'login' 221 | $app->map('/login', function () use ($app) { 222 | $username = null; 223 | 224 | if ($app->request()->isPost()) { 225 | $username = $app->request->post('username'); 226 | $password = $app->request->post('password'); 227 | 228 | $result = $app->authenticator->authenticate($username, $password); 229 | 230 | if ($result->isValid()) { 231 | $app->redirect('/'); 232 | } else { 233 | $messages = $result->getMessages(); 234 | $app->flashNow('error', $messages[0]); 235 | } 236 | } 237 | 238 | $app->render('login.twig', array('username' => $username)); 239 | })->via('GET', 'POST')->name('login'); 240 | ``` 241 | 242 | ### Logout Route 243 | 244 | As authentication stores the authenticated user's identity, logging out 245 | consists of nothing more than clearing that identity. Clearing the identity is 246 | handled by `Authenticator::logout`. 247 | 248 | ``` 249 | $app->get('/logout', function () use ($app) { 250 | $app->authenticator->logout(); 251 | $app->redirect('/'); 252 | }); 253 | ``` 254 | 255 | ## And Done 256 | 257 | That should get you most of the way. I'll complete documentation as soon as I'm 258 | able, but can't currently commit to an ETA. Again, please feel free to open and 259 | issue with any questions you might have regarding implementation. 260 | 261 | Thanks for considering Slim Auth for your project. 262 | 263 | [1]: http://slimframework.com/ 264 | [2]: http://framework.zend.com/manual/current/en/modules/zend.authentication.intro.html 265 | [3]: http://framework.zend.com/manual/current/en/modules/zend.permissions.acl.intro.html 266 | [4]: http://docs.slimframework.com/#Route-Names 267 | [5]: http://docs.slimframework.com/#Route-Helpers 268 | [6]: https://packagist.org/packages/jeremykendall/slim-auth 269 | [8]: https://github.com/ircmaxell/password_compat 270 | [9]: https://github.com/jeremykendall/password-validator 271 | [10]: https://github.com/jeremykendall/slim-auth-impl 272 | [11]: http://getcomposer.org 273 | [12]: http://php.net/manual/en/book.pdo.php 274 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | project.basedir = . 2 | passthru = true 3 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 53 | 54 | 55 | 56 | 57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jeremykendall/slim-auth", 3 | "description": "Authorization and authentication for the Slim Framework using ZF2 Authentication and Acl components", 4 | "homepage": "https://github.com/jeremykendall/slim-auth", 5 | "support": { 6 | "issues": "https://github.com/jeremykendall/slim-auth/issues", 7 | "source": "https://github.com/jeremykendall/slim-auth" 8 | }, 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Jeremy Kendall", 13 | "homepage": "http://about.me/jeremykendall", 14 | "role": "Developer" 15 | } 16 | ], 17 | "keywords": [ 18 | "auth", 19 | "authorization", 20 | "authentication", 21 | "slim", 22 | "slim framework", 23 | "zend", 24 | "zend framework", 25 | "zf2" 26 | ], 27 | "require": { 28 | "php": ">=5.5.0", 29 | "jeremykendall/password-validator": "3.*", 30 | "zendframework/zend-authentication": "2.*", 31 | "zendframework/zend-permissions-acl": "2.*", 32 | "zendframework/zend-session": "2.*" 33 | }, 34 | "require-dev": { 35 | "phpunit/phpunit": "4.*", 36 | "slim/slim": "^3.0", 37 | "jeremykendall/debug-die": "0.0.1.*" 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "JeremyKendall\\Slim\\Auth\\": "src/" 42 | } 43 | }, 44 | "autoload-dev": { 45 | "psr-4": { 46 | "JeremyKendall\\Slim\\Auth\\Tests\\": "tests/" 47 | } 48 | }, 49 | "suggest": { 50 | "zendframework/zend-db": "For the Zend\\Authentication\\Adapter\\DbTable adapters." 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /phpdoc.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Slim Auth 4 | 5 | ./build/docs 6 | 7 | php 8 | 9 | 10 | 11 | ./build/docs 12 | 13 | 14 | ./src 15 | 16 | 17 |