- laravel authorizeResource всегда запрещает доступ
- 3 ответа
- authorizeResource() and nested resources support #1612
- Comments
- royduin commented Apr 20, 2019
- axeloz commented May 13, 2019 •
- pauladams8 commented Jul 27, 2019 •
- KeithBush commented Dec 23, 2019
- PHP/Laravel – Расширение authorizeResource для работы с пользовательским методом
- Policy not working #16184
- Comments
- trunglh88 commented Oct 30, 2016 •
- Description
- prateekkathal commented Oct 30, 2016 •
- trunglh88 commented Oct 30, 2016 •
- laravel authorizeResource always denies access
- 4 Answers 4
laravel authorizeResource всегда запрещает доступ
Я создал контроллер ресурса для конечной точки API. Я также создал соответствующую политику для модели.
Если я делаю проверку авторизации на метод с помощью
Тогда это работает как ожидалось. Но если я добавлю следующее к конструкции, я всегда получаю 403 запрещено. Не уверен, что мне не хватает, так как следующие должны применять авторизацию для всех методов.
Вот как выглядит мой маршрут:
Моя политика зарегистрирована так:
Мой метод политики удаления
Конструктор контроллера API выглядит следующим образом:
Метод контроллера API
Я предполагаю, что что-то упускаю, но я не вижу этого, ворота показываются как запрещенные в телескопе. единственная странная вещь — то, что источником проблемы является serveNova промежуточное программное обеспечение.
Время 8 мая 2019, 10:51:37 (14м. Назад)
Имя хоста core-hosp
Возможность удаления
Результат отклонен
Местоположение /home/vagrant/code/nova/src/Http/Middleware/ServeNova.php:25
Запрос Просмотр запроса
Теги Auth: 1
3 ответа
Я описал свои уроки, связанные с этой утомительной проблемой здесь: https: // github .com / Laravel / рамки / вопросы / 22847 # issuecomment — 521308861. Может быть, кто-то найдет это полезным.
У меня была та же проблема, и я решил ее, изменив сигнатуру методов контроллера. По умолчанию контроллеры получают целое число $id для ссылки на модель, а политики получают непосредственно экземпляр модели. Моя интуиция заключается в том, что сопоставление между контроллером и политикой невозможно.
Итак, я предлагаю попробовать изменить метод вашего контроллера на:
Я не знаю, если это ошибка? Я не нашел документов об этих соглашениях подписи типа метода.
Я обнаружил, что получение правильного параметра идентификатора модели для authorizeResource было очень сложным. Когда параметр отсутствует или не передан должным образом, шаг до того, как политика выдает ошибку (не сама политика, потому что запрос никогда не поступает в политику). В моем случае это означало, что мое промежуточное программное обеспечение CheckUserActive выдавало ошибку, даже если ошибка была в функции Construct контроллера (а не промежуточного программного обеспечения). Несколько замечаний по параметру, который ищет AuthorizeResource:
- Должно быть в нижнем регистре, даже если параметр объявлен в верхнем регистре в вашей модели.
- Должна быть строкой (без переменной, определяющей $, которая используется во многих примерах.)
- Должен быть внутри одинарных кавычек.
Источник
authorizeResource() and nested resources support #1612
Comments
royduin commented Apr 20, 2019
When we’ve a post with comments we can use:
In our PostController , with a PostPolicy and the reference in the AuthServiceProvider . But; when we can’t use authorizeResource() in the CommentController when we’ve nested them:
And we need access to the post and the comment in the CommentPolicy . For example:
This is currently only possible by specifying the authorization in every controller method, for example:
With this example you can say; sure but you can access the post from the comment right? Just use $comment->post in the policy and you’re done. But what about the create method in the policy? For example; a user may only create a comment when the post is published:
To accomplish this we’ve to use:
It would be cleaner to have the possibility to use authorizeResource() with nested resources so we don’t have to specify authorization in every restful controller method.
The text was updated successfully, but these errors were encountered:
axeloz commented May 13, 2019 •
I’ve had the exact same problem today when writing a simple API.
To stick to your example, I still had to use the $this->authorizeResource(Post::class) into the CommentController to prevent anyone playing with the post param of the URL /posts/
Also in order to fix the authorization part, I’ve had to add an explicit model binding into RouteServiceProvider :
I find this quite dirty and I’m sure there is a better way to fix. But at least, comments MUST BELONG to a valid Post . And then the Post policy applies.
Hope it helps.
EDIT 1: thinking about it afterwards, the best way to solve this is in my opinion to globally change the implicit model binding method when using nested resources. The where condition I wrote could maybe be automatic in the future. In other words, when using nested resources, you cannot access a child object that does not belong to the parent object. That would solve a lot of things I guess.
pauladams8 commented Jul 27, 2019 •
@royduin
I’ve been having exactly the same problem and decided the best solution for me was to have two layers of policies.
Using your example, I’d create a route group for your post related sub-resources and apply the can:view,post middleware. Your PostPolicy would ensure the post belongs to the authenticated user.
You could then just use $this->authorizeResource(Comment::class); in the comment controller and use the CommentPolicy to ensure the comment belongs to the post, without needing to worry about authorising access to the post at that stage.
KeithBush commented Dec 23, 2019
I came up with a workaround that allows you to use authorizeResource in a nested resource pattern as long as the nested resource is included in the route path.
IMHO, the docs should contain an example of how to handle this scenario (similar to my example below) or the implementation of authorizeResource should be updated to allow passing additional resources needed for nesting.
My nested context is a little different than the Posts -> Comments relationship but I’ll rewrite everything to use the previously mentioned example as it may be more relatable.
First, for this to work, the nested resource that you need must exist within the URL.
Your route file may look similar to this:
In your CommentController.php, you need a __construct method that calls authorizeResource .
In your CommentPolicy.php, you need a __construct method that does this:
Then in your individual policy checks, you should be able to access $this->post to get the nested resource from within the method.
If this is documented somewhere, I couldn’t find it. At a minimum, I think it would be very helpful to have a similar example listed in the docs under Authorization.
Источник
PHP/Laravel – Расширение authorizeResource для работы с пользовательским методом
У меня есть контроллер ресурсов под названием StreamController.php , который использует политику под названием StreamPolicy.php .
В моем контроллере у меня есть это:
С учетом вышеизложенного все конечные точки RESTful успешно “защищены” с помощью политики.
Тем не менее, я добавил новый метод в мой контроллер, называемый documents() , например:
Теперь проблема в том, если я захожу на URL:
example.com/streams/1 и я не являюсь владельцем потока, я получаю страницу 403 – но если я перехожу по адресу: example.com/streams/1/documents и я не являюсь владельцем потока, я могу все еще получить доступ к странице.
Что я делаю неправильно? Как я могу сделать так, чтобы моя политика также покрывала методы documents() в моем контроллере?
Редактировать:
Это мой файл StreamPolicy.php :
Я не знаю точно, почему это не работает, но я боюсь, что метод authorizeResource обрабатывает только маршруты для известных конечных точек ресурсов: просмотр, создание, обновление, удаление и восстановление.
Позже редактирование: посмотрите в документах, чтобы увидеть, какие действия выполняются контроллерами ресурсов https://laravel.com/docs/5.7/controllers#resource-controllers
Что вы должны сделать, это явно установить авторизацию для нового маршрута:
Конечно, метод documents должен существовать в классе StreamPolicy .
Источник
Policy not working #16184
Comments
trunglh88 commented Oct 30, 2016 •
|
Hi all,
i’m using Policy to authorization but it’s not working on all route.
Description
1.Create default controller using
php artisan make:controller PostController —resource
php artisan make:policy PostPolicy —model=Post
3.In PostPolicy return true for each action (view, create, update, delete)
public function view(User $user, Post $post) < return $user->id === 1; >
4.Register policy in the AuthServiceProvider
protected $policies = [ ‘App\Model’ => ‘App\Policies\ModelPolicy’, Post::class => PostPolicy::class, ];
5.In web.php add routes
6.in PostController add authorizeResource method
public function __construct() < $this->authorizeResource(Post::class); >
7.Access to URL from browser.
Result : Show, Edit link is display correct. (in view check policy is correct ??)
2 routes : edit and show is not working.
The text was updated successfully, but these errors were encountered:
prateekkathal commented Oct 30, 2016 •
Shouldn’t the 2 routes that are not working be like.
post is missing from those 2 routes.
Also, I am unsure as to how you are getting This action is unauthorized instead of 404 Not Found. If you comment out the line having $this->authorizeResource(. ) and try dd(«Post») inside edit() or show() function, does it work?
Lastly, I am unsure as to why you are really using Policies if you are not doing something like
trunglh88 commented Oct 30, 2016 •
This action is unauthorized is exception throw by Illuminate\Auth\Access\AuthorizationException (403 Error)
if i comment out $this->authorizeResource(. ) then inside edit() show() function working fine.
i’m using return $user->id === 1; (user logged or return true; for testing but still error at 2 routes edit() and show()
Источник
laravel authorizeResource always denies access
I have created a resource controller for an API endpoint. I have also created a corresponding policy for the model.
If I do a per method authorization check using
then it works as expected. But if I add the following to the construct, I always get a 403 forbidden. Not sure what I am missing as the following should apply the authorization for all methods.
This is what my route looks like:
My policy is registered like this:
My policy method for deleting is
The API controller constructor looks like this:
The API controller method is
And my routes are
I guess I am missing something but I can’t see it, the gate is being shown as denied in Telescope. the only strange thing is that the serveNova middleware seems to be the source of the issue.
Time May 8th 2019, 10:51:37 AM (14m ago)
Hostname core-hosp
Ability delete
Result denied
Location /home/vagrant/code/nova/src/Http/Middleware/ServeNova.php:25
Request View Request
Tags Auth:1
4 Answers 4
I’ve described my lessons learn with this tiring problem here: https://github.com/laravel/framework/issues/22847#issuecomment-521308861. Maybe somebody will find it useful.
I had the same issue and resolved it by changing the signature of the controller methods. By default controllers receive an integer $id to reference the model, while policies receive directly the model instance. My intuition is that the mapping can’t be made between the controller and the policy.
So, I suggest to try changing your controller method to:
I don’t know if it’s a bug ? I didn’t find docs about these method type signature conventions.
Updated on May 2021:
You can keep the $id as the default param, as you can allow the mapping b/t the controller and the policy by putting the authorization call after the finding the relevant model instance, like this:
I solved this problem by removing the second parameter :
I found that getting the Model identifier parameter correct for authorizeResource was very fiddly. When the parameter is missing or not passed properly, the step before the Policy throws the error (not the Policy itself because the request never makes it to the Policy). In my case, that meant my CheckUserActive middleware was throwing the error, even though the mistake was in the Construct function of the Controller (not the Middleware). A few notes on the parameter that AuthorizeResource is looking for:
- Must be in lower case, even if the parameter is declared in upper case in your model.
- Must be a string (without the variable defining $ that is used in a lot of the examples.)
- Must be inside single tick quote marks.
Источник