Giter VIP home page Giter VIP logo

authorization's Introduction

CakePHP Authorization

Build Status Latest Stable Version Total Downloads Coverage Status Software License

Authorization stack for the CakePHP framework.

Authorization not Authentication

This plugin intends to provide a framework around authorization and access control. Authentication is a separate concern that has been packaged into a separate authentication plugin.

Installation

You can install this plugin into your CakePHP application using composer:

php composer.phar require cakephp/authorization

Load the plugin by adding the following statement in your project's src/Application.php:

$this->addPlugin('Authorization');

or running the console command

bin/cake plugin load Authorization

Documentation

Documentation for this plugin can be found in the CakePHP Cookbook

authorization's People

Contributors

admad avatar amayer5125 avatar back2back avatar burzum avatar davidspeijer avatar dependabot-preview[bot] avatar dependabot[bot] avatar dereuromark avatar enviniom avatar hekep avatar iandenh avatar jadelbe418 avatar jamisonbryant avatar julianpollmann avatar jun-taniai avatar lordsimal avatar markstory avatar mrchozo avatar ndm2 avatar othercorey avatar peter279k avatar ravage84 avatar robertpustulka avatar saeideng avatar stickler-ci avatar swiffer avatar waspinator avatar yuki-yasumura avatar zachee54 avatar zuluru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authorization's Issues

[9.0.0] probleme when not authorized

Hello,

I'm using cakedc/user plugin,
I have a problem with the redirect url when a user isn't authorized, i added this in my user.php :

'AuthorizationMiddleware' => [
           'unauthorizedHandler' => [
               'exceptions' => [
                   'MissingIdentityException' => 'Authorization\Exception\MissingIdentityException',
                   'ForbiddenException' => 'Authorization\Exception\ForbiddenException',
               ],
               'className' => 'Authorization.CakeRedirect',
///////////--------------------------------------------				
   			// -- define the Url for unauthorized :
   				 'url'=>[
   					 'plugin' => null,
   					 'controller' => '',
   					 'action' => 'login',
   				 ]
   			// -- define the name for param of redirect:
   				'queryParam' => 'redirect',
///////////--------------------------------------------
           ]
       ], 

it solved the first redirection to the login form but i still have a problem with the redirection after the login step.

i'm on a subfolder and the redirect url look's like :
http://my.url/cakephp4/login?redirect=http%3A%2F%2Fmy.url%2Fmycontroller%2Fedit%2F6
but it should be :
http://my.url/cakephp4/login?redirect=http%3A%2F%2Fmy.url%2Fcakephp4%2Fmycontroller%2Fedit%2F6
looks like the function in vendor\cakephp\authorization\src\Middleware\UnauthorizedHandler\CakeRedirectHandler.php :

protected function getUrl(ServerRequestInterface $request, array $options): string
    {
		$url = $options['url'];
        if ($options['queryParam'] !== null) {
            $url['?'][$options['queryParam']] = (string)$request->getUri(); <- here
        }

        return Router::url($url);
    }

don't return the good value for the redirect.

MissingPolicyException using Paginator

I tend to use already existing policies to show / hide links, elements, ... in my templates.
Works like expected (setup fine and have various policies in place), but suddenly when paginator comes into the game I get a MissingPolicyException "Policy for Cake\ORM\ResultSet has not been defined" after paginating a resultset. Seems, that the repository can not be resolved after pagination ?

Option 1 (not nice): provide manually the Tablemodel (eg. $user->canResult('export', new AnimalTable());
Option 2 (may be even better and not a workaround): determine acl for elements in view or controller to be displayed on specific template

Example:
Controller:
$query =$this->TheTable->find();
$paginated = $this->paginate($query);

$query2 = $this->TheTable->find();
... set ...

View/Template:
if ($user->can('export', $paginated)) ... MissingPolicyException
if ($user->can('export', $query2)) ... right policy resolved

Would you see it as an issue of the authorization / paginator or probably a design/wrong approach issue ?

Policy for Modelless controller

Hi, I've created a modelless Controller named Principal, and it works like pages, but I don't know how to make policies for actions in this controller. I baked a PrincipalPolicy, and created the method

public function configuration(IdentityInterface $user)
{
    return $user->rol_id === 1;
}

In action "configuration" in PrincipalController I called $this->Authorization->authorize(); but, throws an error about "Too few arguments to function", and I used $this->Authorization->authorize('configuration'); and throws and error about "Policy for string has not been defined".

I don know how to implementa policy for a modelles controller.

Cannot install in versions 3.x

Cake version: 3.8.7
Command: composer require cakephp/authorization
Output: cakephp/authorization 2.0.2 requires cakephp/cakephp ^4.0 -> satisfiable by cakephp/cakephp[4.0.0, 4.0.0-RC1, 4.0.0-RC2, 4.0.0-alpha1, 4.0.0-alpha2, 4.0.0-beta1, 4.0.0-beta2, 4.0.0-beta3, 4.0.0-beta4, 4.0.1, 4.0.2, 4.x-dev] but these conflict with your requirements or minimum-stability.

Can I use can[Action] in a view?

I would like to check authorization actions such as canEdit, canCreate etc. in a cake view so that I can display or omit related links to other views/actions appropriately. At present I use authorization in the controller successfully with each of the canAction checks in the controller actions, but the user experience then means they click a link and receive an authorization failure.

I’d prefer to only show relevant links as well. Not to substitute for the checks in the controller (smart users could type commands into url bar or use curl to circumvent) but to supplement them for a better front end experience.

There is a simple view helper for authentication, do we need one for authorization too or is there an elegant solution I’ve missed?

RequestAuthorizationMiddleware config redirect url missing

I try to use to add the RequestAuthorizationMiddleware for some controller in my application in cake 4.
In the Authorization Middleware i see a code block like this:

$middlewareQueue->add(new AuthorizationMiddleware($this, [
    'unauthorizedHandler' => [
        'className' => 'Authorization.Redirect',
        'url' => '/users/login',
        'queryParam' => 'redirectUrl',
        'exceptions' => [
            MissingIdentityException::class,
            OtherException::class,
        ],
    ],
]));

I can add a redirect url if the authorization failed.
This work fine but how i can add a redirect url for the Request Authorization Middleware ?

"Call to a member function getOriginalData() on null" Cake4 - RequestAuthorizationMiddleware

  • bug

  • enhancement

  • feature-discussion (RFC)

  • CakePHP Version: 4.1.0

I followed the implementation of the Request Authorization Middleware : https://book.cakephp.org/authorization/2/en/request-authorization-middleware.html
My objective is to setup a global security by checking the user role. So i created a RequestPolicy.php with the function canAccess.
It works well however when the session is expired, it still calls the function canAccess which uses $identity which is null because of the expired session so i get an error “Call to a member function getOriginalData() on null” ($identity->getOriginalData()) instead of redirecting me to the login with the redirect param.
I do not understand how it is supposed to handle that case.

MissingIdentityException unused

I traced a difference between the two versions of the plugin I'm using to this commit: e682a4c

In it, the MissingIdentityException is no longer thrown (it now throws a ForbiddenException). This prevents an unauthorizedHandler from redirecting to the login page when no one is logged in during an authorization check. All of the documentation mentions catching this exception as examples of using the unauthorizedHandler.

What would be a way to continue supporting the previous MissingIdentityException behavior while still preserving the fix that commit intended?

Concrete use cases

Is there any way to see a real implementation of this plugin ?

I understand the idea for using it, but I'd like to see some exemple / use cases to know how to use it correctly.

Thxs

Unexpected behavior when using ResolverCollection and mapping a Table class to a Policy

Problem Description

For ease of use, I wanted to minimize the amount of policies needed. In this case I have a CoinPolicy which is the policy for everything what is related to Coins (Coin (Entity) and CoinTable (Table)).
This CoinPolicy implements can() methods and scopes.

While using solely ORM resolver, the plugin expects me to have a CoinPolicy (for the can() methods) and a CoinsTablePolicy for the scopes.

However, I wanted to map the CoinsTable::class to the CoinPolicy::class in order to use one class.

As suggested here, I implemented the Resolvercollection like:

$orm = new OrmResolver();
$map = new MapResolver();
$resolver = new ResolverCollection([$map, $orm]);

In the map resolver I defined the mapping (E.g. \App\Model\Table\CoinsTable::class => \App\Policy\CoinsPolicy::class). So I expect:

  1. The Map resolver checks first for an existing mapped policy,
  2. In case not found, the ORM resolver is the fallback

However when I call in the controller $this->Authorization->applyScope($query, 'adminIndex'); where $query comes from the CoinsTable repository, it results in an error, while it sees the resource $query as instance of Cake\ORM\Query and starts looking for the QueryPolicy instead of the CoinsPolicy
However, I would expect the MapResolver to find my mapped CoinsTable::class and return the CoinsPolicy. This does not happen.

Where in Code

The OrmResolver::getPolicy($resource) checks if the $resource is instance of EntityInterface, RepositoryInterface or QueryInterface and searches for the corresponding EntityPolicy or a RepositoryPolicy.
The MapResolver does not map the Entity/Repository Interfaces to corresponding Policies before trying to find a mapped policy.

Proposed solution

I suggest to update the Mapresolver::getPolicy() and replace $class = get_class($resource) in order that $class is the same type what the getPolicy method is searching for in the OrmResolver

Do we want to provide routes / route scope auth out of the box?

Do we want to allow people to authorize against a resolved route or route scopes?

If yes, any ideas on how to do it the best? Through a middleware?

Common use case: /admin or other prefixes for areas that only an identity with a specific role is allowed to access.

Routing problems in authorization plugin

This is a (multiple allowed):

  • bug

  • enhancement

  • feature-discussion (RFC)

  • CakePHP Version: 4.x-dev

  • Authorization plugin Version: 2.x-dev

  • Platform and Target: XAMPP, URL of Cake installation http://localhost/subdir/

What you did

Integrating authorization plugin. I did the setup/config according to the book and attached the plugin to the middleware trying to get things going.

What happened

The "unauthorizedHandler" config in AuthorizationService set to "/users/login" redirects to "http://localhost/users/login" ignoring the subdir.

What you expected to happen

Routing in the authorization plugin should recognize the subdir where Cake is installed.

encapsulate decision logic

I've dug through the documentation and spent hours trying to find a way to do this. I have nested associations that run several layers deep, and cannot seem to find a place to put decision logic. E.g., I have Users that belong to many Courses through CourseMemberships, and the CourseMemberships have fields that need to be checked (e.g., valid dates) before the policy method can return true or false.

I cannot find a place to encapsulate this logic so that I don't have to copy and paste it between policies and methods for my two dozen models. For example, if this were Controller level rather than policy, I would just dump it all into a component and call that when it's needed. Is there somewhere to put all this and I'm just missing it?

integreting with authentication plugin

I'm trying to add authentication+authorization to an app using this and its related authentication plugin.

I first followed the guide for using the Authentication plugin, and things seemed to be working okay. After adding Authorization, I'm getting an Call to undefined method Authentication\Identity::setAuthorization() error after logging in.

My User entity implements the identity interface class User extends Entity implements IdentityInterface and has a setAuthorization function, as described in https://book.cakephp.org/authorization/1.1/en/middleware.html#identity-decorator

    public function setAuthorization(AuthorizationService $service)
    {
        $this->authorization = $service;

        return $this;
    }

In the a Application middleware() function I added the two new middlewares.

    $authentication = new AuthenticationMiddleware($this, [
        'unauthenticatedRedirect' => Router::url('/users/login')
    ]);

    $authorization = new AuthorizationMiddleware($this, [
        'identityDecorator' => function (AuthorizationService $authorization, Identity $user) {
            return $user->setAuthorization($authorization);
        }
    ]);

    $middlewareQueue->add($authentication);
    $middlewareQueue->add($authorization);

    return $middlewareQueue;

If I try to return the user directly from the identityDecorator I get a Invalid identity returned by decorator. 'Authentication\Identity' does not implement 'Authorization\IdentityInterface'. runtime exception .

Which configuration options am I missing to get things to work together correctly?

Cake 3.6 compatibility

The line below should be updated to getRepository() but when doing this some tests fail because getRepository() is not implemented in Cake\Datasource\QueryInterface, instead it is available in Cake\Datasource\QueryTrait. I didnt open a PR for this because it should be updated in core first.

return $this->getRepositoryPolicy($resource->repository());

requireScope similar to requireAuthorizationCheck?

I'm migrating to the new authorization plugin and I'm really impressed as policies are allowing me to remove all kinds of tenant specific logic. However, a couple of times i've inadvertently stumbled as some of my actions deal with both entities and queries in the same request.

Because i've added an entity authorize() check, nothing is enforcing me to add a scope where needed. Should this be provided as another config option?

We'd somehow have to know whether a scope has been applied to a query already, and then throw an error if the 'requireScope' or similar was true.

Thoughts? Am I missing something here?

Missing authorization for DebugKit

I'm playing around with the Authorization middleware and followed the documentation. The authorization middleware seems to break the DebugKit plugin. After enabling the authorization middleware DebugKit throws a Authorization\Exception\AuthorizationRequiredException and says:

The request to /debug-kit/toolbar/7d4c0193-714d-4e4e-b48c-341e0f9ed99a did not apply any authorization checks.

So obviously the authorization is missing. How can I give DebugKit the needed authorizations or exclude it completely from the authorization? I guess there is an easy solution but I'm not so deep into the middleware/plugin topic.

Cake4: 500 error after adding AuthorizationServiceProviderInterface

I just implemented a fresh cake4 instance and tried to add the Authentification and Authorization plugin interfaces (branch 2.x). Authentification seems to work as expected. After adding the AuthorizationServiceProviderInterface to the Application class, the application breaks with statuscode 500. Any suggestion on that?

FR: visualization of policies

With CakePHP2 we used ACL; it was very straightforward to show which role/user is authorized to do 'something'.
Now (CakePHP4) we use policies, which have no such visual aspect.

During CakeFest we got a glimpse at the statemachine. A feature that impressed me was the visualization of the UML.
Wouldn't it be a great feature to have a visualization component in the authorization plugin?

Support policy factories

I have a case where my ORM policies need some dependencies. I'd like to pull those from a DIC. I was thinking that it may be a good idea to add support for policy factories. The feature might be useful with an upcoming core DIC support.

How this may work?

interface PolicyFactoryInterface
{
    public function create(string $className): object;
}

class DefaultPolicyFactory implements PolicyFactoryInterface
{
    public function create(string $className): object
    {
        return new $className;
    }
}

class OrmResolver implements ResolverInterface
{
    public function setFactory(PolicyFactoryInterface $factory): void
    {
        $this->policyFactory = $factory;
    }

    protected function getFactory(): PolicyFactoryInterface
    {
        if (!$this->policyFactory) {
            $this->policyFactory = new DefaultPolicyFactory;
        }
        return $this->policyFactory;
    }

    protected function findPolicy(string $class, string $name, string $namespace)
    {
        ...

        return new $this->getFactory()->create($policyClass);
    }
}

We would need to update all resolvers to use a factory internally, but with an optional setter injection this should be BC.

ORM Policy resolver broken

I have a couple of projects in which multidimensional data reside in some 4 to 10 main tables. The remaining tables in the projects are lookup tables that define the vocabulary. These tables should be viewable by every logged on user, but only be editable by administrators. Since I only have 2 sets of Authorization logic (except the users table, which is special), I only want to implement 2 policies and otherwise use the ORM resolver to map my entities to just 2 policies. I developed under the latest CakePHP, which is 4.1, and the latest cakephp/auhorization, which is 2.0.5.

In the /src/Application.php I called the ORM resolver as specified in the cookbook:

public function getAuthorizationService(ServerRequestInterface $request): AuthorizationServiceInterface
    {
        $appNamespace = 'App'; // is the default
        $overrides = ['Confirmation' => 'Glossary',
                      'Institution' => 'Glossary',
                     ];
        $resolver = new OrmResolver($appNamespace, $overrides);
     }

However, this did not have the desired effect. Whenever I overrode the policy name, I got an error "Missing Policy Exception" from line 148 of ./vendor/cakephp/authorization/src/Policy/OrmResolver.php

Finally, I found the issue. Line 134 in ./vendor/cakephp/authorization/src/Policy/OrmResolver.php needs to be changed:

protected function findPolicy(string $class, string $name, string $namespace)
   {
       // $namespace = $this->getNamespace($namespace); // original statement, M. B.
       $name = $this->getNamespace($name); // correct statement, M. B.
       $policyClass = null;

      (...)

       if ($policyClass === null) {
           throw new MissingPolicyException([$class]);
       }

       return new $policyClass();
   }

The call to the protected function getNamespace needs to be made with the name of the entity (e.g. $name = 'Confirmation'), not with the appNameSpace (which is $namespace = 'App'). With this minor change in OrmResolver.php things work as they should.

Release incorrect

As stated on slack:
"pssst @markstory you released a new version of this plugin including the new RequestAuthorizationMiddleware, but somehow it's still an older version of the branch, (12 commits behind) so its missing that middleware :-)"

[RFC] Support plugin map in OrmResolver

I have a use case, where I have my app logic in a plugin (let's cal it a logic plugin) and use there some models from another plugin (call it data plugin).

Currently the only way to define policies for my models is to:

  • add policies to the "data plugin" (not possible in my case)
  • add policies to my app (breaks my design, where logic is defined in a logic plugin)
  • use map resolver and map each "data plugin" model to the policy in a "logic plugin" (makes little sense)
  • extend each "data plugin" model in "logic plugin" model and use those instead (still lots of senseless work)

My idea is to have the ability to map plugins in a resolver so the policies would be looked for in another plugin. For example:

new OrmResolver([
    'appNamespace' => 'MyApp',
    'pluginMap' => [
        'DataPlugin' => 'LogicPlugin'
    ]
]);

What is your opinion on this?

Can't use i18n and get plugin in different locale

After using the plugin in a Cakephp 3.8 app, I realized that you cannot use bin\cake i18n extract to get the plugin in your app locale.

It would be nice to be able to use this tool as for cake core.

Flash messages and redirect URLs for authorization failures

I don't see any way to set the flash message that gets used in case of authorization (or authentication) failures, or provide custom redirect URLs for different policy failures (e.g. redirect to a view when edit isn't allowed). I've tried added this capability in my app by writing my own "unauthorized" handler and throwing custom exceptions from my policies; the handler pulls the required details from these and proceeds accordingly. But while the exceptions work okay for actual authorization checks ($this->Authorization->authorize()), they cause problems when doing authorization tests ($this->Authorization->can()).

I've had to write quite a bit of code to get close to functionality that the old Auth component had, so I feel like I may be missing something. Or maybe the plugins just haven't had it added yet? Happy to work towards a PR if this is the sort of thing that the plugin should support natively.

Allow for AuthorizationComponent::can to not set $authorizationChecked

I use AuthorizationComponent::can to check if a particular menu item should be shown (menu array is set as viewVar), this then breaks the requireAuthorizationCheck security feature. It would be good if we can pass an option to can that stops $authorizationChecked being set to true. Alternatively add another method AuthorizationComponent::check which does this, although this might be confusing.

Example

if ($this->Authorization->can(new AdminUser(), 'index')) {
    $sideBar[99] = [
        'text' => 'System',
        'icon' => 'fa-dashboard',
        'subItems' => [
            [
                'text' => 'Admin Users',
                'url' => ['controller' => 'AdminUsers', 'action' => 'index'],
            ]
        ]
    ];
}

After doing this if I miss adding a can / canResult to an action no exception is thrown and the action is open

Can't implement __call() on a policy object.

I'm trying to implement __call() in a policy so I can delegate the data to a lookup in a database table.

This doesn't work because method_exists() doesn't check for `__call() .

Can I push this change?

    protected function getCanHandler($policy, $action)
    {
        $method = 'can' . ucfirst($action);

        if (!method_exists($policy, $method) && !method_exists($policy,' __call')) {
            throw new MissingMethodException([$method, $action, get_class($policy)]);
        }

        return [$policy, $method];
    }

Custom bake Policy template

Hi,

Is is posible to create a custom bake template for the policy?

I've created /src/Template/Bake/policy.twig (cakephp 3.x) But this file is not used when I run the bake command. I need to change some little things in template for my project. Else I have to edit it every time when I make a new Policy.

Error to test login with phpunit: setAuthorization()

I add authentication plugin and authorization plugin to my CakePHP App.

On web broswer login works right.

I'm try to test it with PHPUnit and i receive some errors.

On my test i run this:

$config = TableRegistry::getTableLocator()->exists('Users') ? [] : ['className' => UsersTable::class];
$users = TableRegistry::getTableLocator()->get('Users', $config);
		
$user = $users->get($userId);
$this->session(['Auth' => $user]);

$this->enableCsrfToken();
$this->enableSecurityToken();

// call
$this->get('Users/login');

$this->assertResponseSuccess(); // Check for a 2xx/3xx response code

In my Application.php

new AuthorizationMiddleware($this, [
	'identityDecorator' => function (AuthorizationService $auth, ArrayAccess $user) {
		debug($user);die;
		return $user->setAuthorization($auth);
	},
	'requireAuthorizationCheck' => false,
	'unauthorizedHandler' => [
		'className' => 'Authorization.Redirect',
		'url' => '/users/login',
		'queryParam' => 'redirectUrl',
		'exceptions' => [
			MissingIdentityException::class,
			OtherException::class
		]
	]
])

debug print on test show:

########## DEBUG ##########
object(Authentication\Identity) id:0 {
  'config' => [
    'fieldMap' => [
      'id' => 'id'
    ]
  ]
  'data' => object(Cake\ORM\Entity) id:1 {
    'id' => (int) 1
    'role_id' => (int) 1
    'status_id' => (int) 1 ...
 

On Web Browser show:

object(App\Model\Entity\User) id:0 {
	'id' => (int) 1
	'role_id' => (int) 2
	'status_id' => (int) 1 ...

Error, in testCase on cli-error.log is

Call to undefined method Authentication\Identity::setAuthorization()

Which configuration options am I missing to get things to work together correctly?

skipAuthorization doesn't work when using RequestPolicy

Hello,

I`m using CakePHP4 and I noticed that $this->Authorization->skipAuthorization(); placed in an action doesn't work when using RequestPolicy.

I have a simple RequestPolicy that retrieves some access rows from the database based on the user's group.

Can you help me with this?

Thank you!

Authorization Identity can() method need to allow second parms to optional.

I am using Authorization plugin and created Policies and these policies working good in the controller like can index/add/edit/delete but i have issue in the view index.php there i need to hide add button using can() method like below


if($this->request->getAttribute('identity')->can('add')){
         echo $this->Html->link("<i class=\"fa fa-plus\"></i> " . __('New User'), ["action" => "add"], ["escape" => false]);
  }

There we need second parameter newEmptyEntity object but i am in index function so i don't want to add newEmptyEntity object. when i used above script for hide add button then this error will be appear

(Error: Too few arguments to function Authorization\IdentityDecorator::can(), 1 passed in index.php on line 21 and exactly 2 expected.)

My policy method is this one:

public function canAdd(IdentityInterface $user)
    {
        if($user->is_supper_admin){
            return true;
        }
        return false;
    }

In this case i don't need second parameter so please resolve this issue

image

Thanks

Problems with orm resolver and map resolver (server request) in collection

I am really sorry if this is not the properly place to ask this.

My application handles both "things" that can be identified as entities (they have associated models/tables) and also at least one "thing" that does not have any model associated. This is mainly the portal users logging into the system by default land on.
Since it does not have a model associated, the orm resolver will start complaining that no policy for Cake\ORM\Table is defined. Now, I could ofcourse deicde to skipAuthorization but this is action based and not controller.action based.

I would need to either assign a specific action to the portal landing page to skip authorization which I really don't feel comfortable with.

Now I have been looking at adding the RequestAuthorization middleware and use both the orm resolver and a map resolver for the request in a resolver collection. This however does not seem to work because either the server request policy is not satisfied (in case this is an orm related entity) and I get a forbidden error, or the server request policy is satisfied and the orm resolver starts complaining that it is missing the Cake\ORM\Policy (in case this is the portal).

It seems that when the one resolver returns true, the other resolver is then checked anyway even though authorization has been granted. I had expected that when one resolver is satisfied, it would skip any other resolver in the collection. Am I wrong? Is this expected behavior?

Also, I have been looking at maybe switching from the Authorization plugin to the Acl plugin but I am not sure if I can't achieve the same with the Authorization plugin as would be possible with the Acl plugin.

Redirect is not working for me

Hi, I can't make a redirect for unathorized actions, and i made configuration like say in docs:

'unauthorizedHandler' => [
                    'className' => 'Authorization.Redirect',
                    'url' => '/principal/noauthorized',
                    'queryParam' => 'redirectUrl',
                    'exceptions' => [
                        MissingIdentityException::class,
                        OtherException::class,
                    ],
                ], 

But, still shows the error page with "Identity is not authorized to perform (...)" and I can't redirect to /principal/noauthorized

Restricting access for not logged in users

Do we wan't to support some replacement for the AuthComponent:allow()/deny() methods?

Currently AuthorizeComponent requires that the identity is present in a request. There's no build-in way of checking if an identity is present and take some action if it is not (ie redirect to login page or throw a forbidden exception).

Not sure if this feature should belong here or maybe Authentication plugin?

RFC - Query Policies

When generating list views, or getting a list of resources, it is simpler and more efficient to bake authorization restrictions into the generated query.

Unfortunately, our existing paradigm of can() : bool does not match well to mutating queries as there would be an implicit side-effects with a useless return.

To make the side-effect and intent more specific I think we should expand the IdentityInterface and AuthorizationServiceInterface to have a new method that allows for queries to have authorization rules applied to them.

// From an IdentityDecorator instance.
$query = $user->authorizeQuery($this->Articles->find(), 'index')

// From the AuthorizationComponent
$query = $this->Authorization->authorizeQuery($this->Articles->find(), 'index')

This API would result in a policy being located for $query->respository(). Once located the policy instance would have its authorizeIndex method invoked. In the above scenario App\Policy\ArticlesPolicy::authorizeIndex($user, $query) would be invoked, and be required to return an updated query object.

Prior Art

Authorization check on OPTIONS request

Hi,

I've just started implementing authorization plugin in our cakephp 3 project.

Now I've added $this->Authorization->skipAuthorization(); to a function. When I do a GET request it works fine. but when I do a OPTIONS request I still get a 500 server error with message that no authorization has been applied.

should this check not been skipped with a "OPTIONS" request? Looks like authentication check is skipped for the request type.

At the moment my frontent can't do requests because it does a OPTIONS request before it does the real request.

AuthorizationComponent::authorize() should now throw an exception

I think this should return bool instead. The exception should be thrown in authorizeAction() because this is the automated action check and it is likely that I don't want to display it at all. But authorize() should give me the option to decide what I want to do instead of requiring me to wrap the call in a try/catch.

@markstory told me this on Slack before he went offline:

The middleware lets you configure how unauthorized exceptions are handled. Does it need to be in the component?

If the article is not allowed to be viewed I want to show a flash message and redirect back to from where ever the user came from and not relying on a generic handler, probably redirecting me to a login page. Or what if I would like to stay on the current page but render a paywall like page? I would have to handle the exception again. An exception feels wrong here in any case. It's not an exception but an expected result that I either can or can't access the action.

Component doesn't handle non-object resources

In a number of places through the plugin, calls to get_class($resource) are preceded by if (is_object($resource)). But in AuthorizationComponent::authorize, if the action is not authorized, the parameters passed to the ForbiddenException constructor don't have this check, they just call get_class($resource). I am building a resolver that just takes a string for the policy class name instead of deducing it from an object, and it fails in these cases because of this. It seems that this is likely just an oversight; I can easily put together a PR to correct it, if it's an actual defect instead of intentional behaviour.

`can` documentation issue?

should the parameters in can($this, $action, $resource); be switched to can($this, $resource, $action); in the documentation?

It seems different in

public function can($resource, $action = null)

https://book.cakephp.org/authorization/1.1/en/middleware.html#identity-decorator

class User extends Entity implements IdentityInterface
{

    /**
     * Authorization\IdentityInterface method
     */
    public function can($action, $resource)
    {
        return $this->authorization->can($this, $action, $resource);
    }
...

The request to * did not apply any authorization checks when using PRG pattern.

I'm using the https://github.com/FriendsOfCake/search/ plugin to filter data.

The Search.Search component will allow your filtering forms to be populated using the data in the query params. It uses the PRG pattern (Post, redirect, get). (https://github.com/FriendsOfCake/search/tree/master/docs)

It appears that this authorization plugin cannot handle this pattern as I get the following error:
The request to /orders/index did not apply any authorization checks.

I also described the issue at FriendsOfCake/search#265 however the response over there was that this is an issue with the authorization plugin.

my function in the controller:

public function index() {
    $this->paginate = [
        'contain' => [
            'Companies',
            'ShippingBarcodes' => ['sort' => ['ShippingBarcodes.id' => 'DESC']]
        ],
        'order' => ['Orders.id' => 'DESC']
    ];
    
    $orders = $this->Orders->find('search', ['search' => $this->request->getQueryParams()]);
    $this->Authorization->authorize($orders);
    $orders = $this->paginate($orders);

    $companies = $this->Orders->Companies->find('list')->where(['Companies.published' => true])->order(['Companies.name' => 'ASC']);
    $statuses = Order::status();

    $this->set(compact('orders','companies','statuses'));
}

This is loading the page as expected. The problems occurs once I try to filter the results. The POST results in a status 500:

The request to/orders/index did not apply any authorization checks.

Adding a skipAuth is not solving the problem:

public function index() {
    $this->Authorization->skipAuthorization();

    $this->paginate = [
        'contain' => [
            'Companies',
            'ShippingBarcodes' => ['sort' => ['ShippingBarcodes.id' => 'DESC']]
        ],
        'order' => ['Orders.id' => 'DESC']
    ];
    .........
}

As suggested in FriendsOfCake/search#258 I tried to catch the problem in beforeFilter();

public function beforeFilter(\Cake\Event\EventInterface $event)
{
    parent::beforeFilter($event);
    if ($this->request->getParam('action') == 'index' && $this->Authentication->getIdentity()->get('role') == 'admin') {
        $this->Authorization->skipAuthorization();
    }
}

This is "solving" the issue as a workaround.

However not as I expect it to work. As I assume that the $this->Authorization->skipAuthorization() or $this->Authorization->authorize($orders) in the index method should have applied the auth check even with the redirect?

I'm open to any suggestions.

conventions for table and query policy

I'm not sure if the conventions for table objects and query policies are missing from the docs or if I'm not reading things right. And just checking,bake only generates entity policy files at the moment?

entity: cake bake policy User
table: cake bake policy --type=table Users creates something fairly bare-bones

https://book.cakephp.org/authorization/1.1/en/policies.html#creating-policies

table objects and queries can have policies resolved. These objects use the following conventions:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.