9

正如官方文档(https://laravel.com/docs/5.3/passport#introduction)中所述,我已经为 Laravel 5.3 设置了Laravel Passport包。

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

$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' => '',
    ],
]);

...按预期工作,为我的一个用户返回访问令牌刷新令牌

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

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

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

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

提前致谢。

4

3 回答 3

5

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

例如,如果您只希望使用来自 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-04-23T01:05:07.267 回答
1

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

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

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

于 2017-06-28T16:29:18.190 回答
0

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

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

于 2019-03-25T19:25:58.070 回答