AuthorityController 
AuthorityController is an PHP authorization library for Laravel 5.3 which restricts what resources a given user is allowed to access.
All permissions are defined in a single location:
config/authority-controller.php
and not duplicated across controllers, routes, views, and database queries.
For Laravel 5.2 supports see AuthorityController 2.2 branch
For Laravel 5.0 or 5.1 supports see AuthorityController 2.1 branch
For Laravel 4.1 or 4.2 supports see AuthorityController 1.2 branch
Demo application
You can see in action this package with this Laravel 5.3 demo application.
Origins and Inspirations
It's an extension of the authority-laravel
package.
And a port of the best Ruby authorization library: CanCan.
Authority ports some features of CanCan and this package ports almost all the other features.
Installation
With Composer
Addauthority-controller
package to your composer.json
file to require AuthorityController:
composer require efficiently/authority-controller:dev-master
Add the service provider to config/app.php
:
EfficientlyAuthorityControllerAuthorityControllerServiceProvider::class, Add the aliases (facades) to your Laravel app config file:
'Params' => EfficientlyAuthorityControllerFacadesParams::class, 'Authority' => EfficientlyAuthorityControllerFacadesAuthority::class, This will allow you to access the Authority class through the static interface you are used to with Laravel components.
Authority::can('update', SomeModel::class);
Configuration
Create Roles and Permissions Tables
We have provided a basic table structure to get you started in creating your roles and permissions.
Publish them to your migrations directory or copy them directly.
php artisan vendor:publish --provider="EfficientlyAuthorityControllerAuthorityControllerServiceProvider" --tag="migrations"
Run the migrations
php artisan migrate
This will create the following tables
roles role_user permissionsTo utilize these tables, you can add the following methods to your User
model. You will also need to create Role and Permission Model stubs (replacing AppAuthority
with you own namespace)..
//app/User.php public function roles() { return $this->belongsToMany(AuthorityRole::class)->withTimestamps(); } public function permissions() { return $this->hasMany(AuthorityPermission::class); } public function hasRole($key) { $hasRole = false; foreach ($this->roles as $role) { if ($role->name === $key) { $hasRole = true; break; } } return $hasRole; }
//app/Authority/Role.php <?php namespace AppAuthority; use IlluminateDatabaseEloquentModel; class Role extends Model {}
//app/Authority/Permission.php <?php namespace AppAuthority; use IlluminateDatabaseEloquentModel; class Permission extends Model {}
Init resource filters and controller methods
In your app/Http/Controllers/Controller.php
file, add the ControllerAdditions
trait and disable the use of the AuthorizesRequests
trait:
<?php namespace AppHttpControllers; use IlluminateFoundationBusDispatchesJobs; use IlluminateRoutingController as BaseController; use IlluminateFoundationValidationValidatesRequests; use IlluminateFoundationAuthAccessAuthorizesRequests; use EfficientlyAuthorityControllerControllerAdditions as AuthorityControllerAdditions; class Controller extends BaseController { // use AuthorizesRequests; use DispatchesJobs, ValidatesRequests; use AuthorityControllerAdditions; //code... }
NB: If you really need the default Laravel Authorization system, you can use the AuthorizesRequests
trait, if you alias its authorize
and authorizeResource
methods, like this:
<?php //code... class Controller extends BaseController { use DispatchesJobs, ValidatesRequests; use AuthorizesRequests, AuthorityControllerAdditions { AuthorityControllerAdditions::authorize insteadof AuthorizesRequests; AuthorizesRequests::authorize as illuminateAuthorize; AuthorizesRequests::authorizeResource as illuminateAuthorizeResource; } //code... }
Getting Started
AuthorityController expects that auth()->user()
return the current authenticated user. Now, by default Laravel 5 handles this.
Defining Authority rules
User permissions are defined in an AuthorityController configuration file.
You can publish the AuthorityController default configuration file with the command below:
php artisan vendor:publish --provider="EfficientlyAuthorityControllerAuthorityControllerServiceProvider" --tag="config"
This will place a copy of the configuration file at config/authority-controller.php
. The config file includes an initialize
function, which is a great place to setup your rules and aliases.
//config/authority-controller.php <?php $serializer = new SuperClosureSerializer; return [ 'initialize' => $serializer->serialize(function ($authority) { $user = auth()->guest() ? new AppUser : $authority->getCurrentUser(); // Action aliases. For example: $authority->addAlias('moderate', ['read', 'update', 'delete']); // Define abilities for the passed in user here. For example: if ($user->hasRole('admin')) { $authority->allow('manage', 'all'); } else { $authority->allow('read', 'all'); } }) ];
See Defining Authority rules for details.
Check Authority rules & Authorization
The current user's permissions can then be checked using the Authority::can()
and Authority::cannot()
methods in the view and controller.
@if (Authority::can('update', $article))
{{ link_to_route("articles.edit", "Edit", $article->id) }}
@endif
See Checking Authority rules for more information
The authorize()
method in the controller will throw an exception if the user is not able to perform the given action.
public function show($id) { $this->article = AppArticle::find($id); $this->authorize('read', $this->article); }
Setting this for every action can be tedious, therefore the loadAndAuthorizeResource()
method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for every action.
<?php namespace AppHttpControllers; class ArticlesController extends Controller { public function __construct() { $this->loadAndAuthorizeResource(); } public function show($id) { // $this->article is already loaded and authorized } }
See Authorizing Controller Actions for more information.
Exception Handling
The EfficientlyAuthorityControllerExceptionsAccessDenied
exception is thrown when calling authorize()
in the controller and the user is not able to perform the given action. A message can optionally be provided.
Authority::authorize('read', 'AppProduct', 'Unable to read this product.');
You can catch the exception and modify its behavior in the render()
method of the app/Exceptions/Handler.php
file. For example here we set the error message to a flash and redirect to the home page.
//app/Exceptions/Handler.php /** * Render an exception into an HTTP response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse */ public function render($request, Exception $e) { //code... if ($e instanceof EfficientlyAuthorityControllerExceptionsAccessDenied) { $msg = $e->getMessage(); Log::error('Access denied! '.$msg); return redirect('/home')->with('flash_alert', $msg); } return parent::render($request, $e); } //code...
See Exception Handling for more information.
Documentations
Wiki Docs
Defining Authority rules Checking Authority rules Authorizing Controller Actions Exception Handling See moreAuthority Docs
Authority introduction.
Authority-Laravel general usage.
CanCan Wiki Docs
Because AuthorityController is a CanCan port, you can also read the Wiki docs of CanCan here.
Controller additions
Your controllers have now a $params
property:
<?php namespace AppHttpControllers; class ProductsController extends Controller { //code... public function update($id) { $this->params['id'] == $id;//-> true $this->params['product'];//-> ["name" => "Best movie"] $this->params['controller'];//-> 'products' $this->params['action'];//-> 'update' //code... } //code... }
Changelog
#### 2.3.0-dev
Laravel 5.3 support!#### 2.2.0
Laravel 5.2 support!#### 2.1.1
Update installation instructions for Laravel >= 5.1.11#### 2.1.0
Laravel 5.1 support!2.0.1
Replace the deprecated packageilluminate/html
package by the laravelcollective/html
package
Autoloading migrations class is useless, see issue #30 (reported by @Fnatte)
Autoloading class from tests
directory are now only available in Composer's dev mode to avoid conflicts
#### 2.0.0
Laravel 5.0 support! Use your Laravel Aliases to resolve your models namespace name. Or auto guessing them, e.g.User
=> AppUser
Add a new config option controllerClass
which is by default IlluminateRoutingController
Support Route Model Binding in the Parameters class.
See: http://laravel.com/docs/5.0/routing#route-model-binding and issue #21
Use authority-laravel package instead of authority-l4.
Upgrade Notes (if you used previously this package with Laravel 4):
Move your authory-controller
config file from app/config/packages/efficiently/authority-controller/config.php
to config/authority-controller.php
Publish the authory-controller
migrations files (see the section Create Roles and Permissions Tables of this README)
1.2.4
AddBaseController::flushAuthorityEvents()
static method.
Useful for functional tests with Codeception (see issue #14 and this Wiki page for more explanations).
Fix User::hasRoles() method to avoid duplicate roles.
1.2.3
Follow PSR-2 coding style1.2.2
Run tests with Laravel 4.21.2.1
Fixcomposer.json
file.
1.2.0
Security fix: conditional callback was never evaluated when an actual instance object was present. Non backwards compatible: Deny rules override prior rules and Allow rules don't override prior rules but instead are logically or'ed (fix #5). Match more CanCan default behavior unlikeauthority-phpauthority
package.
Read the Wiki doc for more information: Authority-Precedence.
Support PHP 5.4, 5.5, 5.6 and HipHop Virtual Machine (hhvm).
Update Parameters
class to allow custom routes with id
and parent_id
routes's parameters (fix #6).
1.1.3
Upgrade Authority-L4 package to fix Laravel 4.1 support.1.1.2
Tweak the mock system who simulates Eloquent's constructor method.1.1.1
Less intrusive parameters injection in the controllers Check if the current resolved controller responds to paramsBeforeFilter method. Otherwise the application crash. Use the Controller alias of the current Laravel application instead of a hardcoded class name.1.1.0
First beta release for Laravel 4.1 compatibility. Non backwards compatible with Laravel 4.0.1.0.0
First stable release, only compatible with Laravel 4.0. For Laravel 4.1 supports, see AuthorityController 1.1 branch. Fix AccessDenied class, the exception message didn't fallback to the default message if it was empty.0.10.0
Non backwards compatible:Params::get('controller')
behaviour is now like Rails. It returns controller name in snake_case and in plural.
0.9.0
First beta releaseMissing features
InControllerResource
class, the #load_collection
method, who uses in the User
model #accessible_by
method. Looks complicated.
Instead, use specific query scopes with collectionScope
option to filtering your data in your collection (e.g. index
) controller actions.
Because you'll allowing/denying access by roles or check user's authorizations on each record of the collection.
In Ability
class, the #attributes_for
method.
Looks useless with Authority
because rules conditions are only possible by Closure
not by associative array. And CanCan handles #attribute_for
only for Hash
(associative array) conditions.
#skip_*
methods in ControllerAdditions
.
For allow()
and deny()
methods of Authority
, the third argument isn't an optional hash (associative array) of conditions but an anonymous function (Closure):
$authority->allow('update', 'AppProduct', function ($self, $product) { return $product->available === true; });
Good to know
Compatibility
It's only compatible with PHP >= 5.6 and Laravel >= 5.3 framework.
Differences between CanCan and AuthorityController
See Wiki page Differences between CanCan and AuthorityController
Philosophy
It's following the D.R.W.J.P.I. principle:
Don't Reinvent the Wheel, Just Port It ! -- (c) 2013 A.D.
Questions or Problems?
If you have any issues with AuthorityController, please add an issue on GitHub or fork the project and send a pull request.
To get the tests running you should install PHPUnit and run phpunit tests
.
Special Thanks
AuthorityController was heavily inspired by CanCan and uses Authority-Laravel.
版权声明:
1、该文章(资料)来源于互联网公开信息,我方只是对该内容做点评,所分享的下载地址为原作者公开地址。2、网站不提供资料下载,如需下载请到原作者页面进行下载。
3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考学习用!
4、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。