【问题标题】:How to limit user actions with Laravel Passport Scopes + Password Grant Type如何使用 Laravel Passport Scopes + Password Grant Type 限制用户操作
【发布时间】:2017-05-06 22:13:39
【问题描述】:

我已经按照官方文档 (https://laravel.com/docs/5.3/passport#introduction) 中的描述为 Laravel 5.3 设置了 Laravel Passport 包。

我希望 API 被移动应用程序使用,因此我正在尝试实现 密码授予令牌。我已经创建了一个密码授予客户端,以及令牌请求过程......

$response = $http->post('http://my-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'my@email.com',
        'password' => 'my-password',
        'scope' => '',
    ],
]);

...按预期工作,为我的一位用户返回 access-tokenrefresh-token

但是现在我想定义一些范围,这样我就可以限制用户的访问...再次按照文档,我在 AuthServiceProvider.php 的 boot 方法中定义了它们 em> 喜欢:

Passport::tokensCan([
    'admin' => 'Perform every action',
    'user' => 'Perform only normal user actions',
]);

在这种情况下,如果“恶意”普通用户请求一个指定'scope' => 'admin' 的令牌(使用上述 POST 调用),他或她将获得一个“管理员”令牌......这不是我想要的。

因此,我想知道这种情况下的工作流程如何有效地限制对普通用户的访问,以及我必须在哪里实现 范围验证逻辑.

提前致谢。

【问题讨论】:

  • 没人知道吗?
  • 我对此也有同样的担忧。关于:blogs.oracle.com/OracleIDM/entry/… 请求的范围可以或应该被授权与令牌绑定,以便没有用户可以访问范围:“*”只是默认令牌请求。我很期待看到答案。我也想知道,为什么通过护照授予访问权限不提供这种功能。也许我们正在考虑这种错误的方式?
  • 这看起来是一种聪明的做法 :) 但这里的关键是不要在每个 'oauth/token 中公开 client_idclient_secret ' 称呼。因此,调用 'api/login' 路由只需要用户名/密码,并且 'oauth/token' 路由总是安全的 :)

标签: php laravel oauth-2.0 laravel-5.3 laravel-passport


【解决方案1】:

我忘记了我在哪里读到的,在某个地方有一些 Github 问题,但显然 Laravel 没有内置该功能,每个客户端都受到同等对待,开箱即用。

一位用户提供了一个很好的解决方案,我在这里建立了它:https://stackoverflow.com/a/55285483/1132557

【讨论】:

    【解决方案2】:

    在我看来,我认为大多数人对 OAuth 和 API 感到困惑的是,作用域与“客户端”相关联,而不是与“资源所有者”本身相关联。如果需要,客户端应该能够使用管理范围或根本不使用范围与 API 对话。如果他们将管理员类型范围与用户上下文(密码授予、授权代码授予等)一起使用,则无法阻止他们在 API 中针对该用户进行需要此类范围的调用。对我来说,唯一可以真正被归类为恶意的人是设法窃取包含管理范围的访问令牌的人。这就是为什么允许 API 实现者指定授予客户端的范围,如果它是使用密码授予之类的第一方应用程序,那么您作为用户别无选择,只能信任您的数据。

    我不知道如何做到这一点并在另一个移动应用程序中使用检索到的令牌,但如果您确实尝试在管理员范围内手动请求令牌,那么我真的看不出有什么问题(除了你给应用程序更多的控制权设置为用户上下文,所以它甚至可能适得其反?)

    如果您需要更多的控制权,那么您需要超越您的 API 并为资源服务器中的每个用户创建类似应用程序级别的权限。

    【讨论】:

      【解决方案3】:

      解决这个问题的一种方法是创建一个中间件

      例如,如果您只希望使用来自 example.com 的电子邮件的用户请求管理域,您可以执行以下操作

      例如ScopeLogic.php中间件:

      if ($request->input('grant_type') === 'password') {
          $scope = $request->input('scope');
          $username = $request->input('username');
      
          if ($scope === 'admin' && (strpos($username, '@example.com') === false)) {
              return response()->json(['message' => "Not authorized to request admin scope"], 401);
          }
      }
      
      return $next($request);
      

      当然,您必须将此范围添加到 Kernel.php 中的 $routeMiddleware 数组中

      protected $routeMiddleware = [
          ...
          'check-scopes' => \App\Http\Middleware\ScopeLogic::class
      ]
      

      以及将Passport::routes() 包装在AuthServiceProvider.php 中以检查此中间件

      \Route::group(['middleware' => 'check-scopes'], function() {
          Passport::routes();
      });
      

      Passport 还会检查是否传递了正确的用户名和护照组合,因此您不必担心中间件中的这些问题

      【讨论】:

        猜你喜欢
        • 2017-03-15
        • 1970-01-01
        • 2020-07-13
        • 2015-06-11
        • 2019-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        相关资源
        最近更新 更多