How to limit user actions with Laravel Passport Scopes + Password type

I installed the Laravel Passport package for Laravel 5.3 as described in the official documentation ( https://laravel.com/docs/5.3/passport#introduction ).

I want the API to be used by the mobile application, so I'm trying to implement password tokens . I created a client to provide a password and a token request process ...

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

... just works as expected, returning an access token and a refresh-token for one of my users.

But now I want to define some scopes to restrict user access ... After re-documentation, I defined them in the AuthServiceProvider.php download method, for example:

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

In this case, if the “malicious” normal user requested a token (using the above POST call) by specifying 'scope' => 'admin' , he or she will receive the “admin” token ... and this is not what I want.

Thus, I would like to know how the workflow in this situation effectively restricts access to ordinary users and where I need to implement the validation logic . .

Thanks in advance.

+8
php laravel laravel-passport
source share
2 answers

One way to do this is to create middleware

For example, if you want users with email from example.com to request an admin domain, you can do something like this

ScopeLogic.php middleware example:

 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); 

Of course you will need to add this area to your $ routeMiddleware array in Kernel.php

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

Like wrap Passport::routes() in AuthServiceProvider.php for checking this middleware

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

The passport also checks the username and passport combination, so you do not need to worry about this in the middleware

+2
source share

In my opinion, I think that most people with OAuth and APIs are confused by the fact that areas are tied to “clients” and not to “resource owners”. Clients should be able to talk to the API using the administration area or have no areas at all, if necessary. If they use an admin-ish type area together with user content (providing a password, permission to provide an authorization code, etc.), then there is no way to stop them from making calls that require such a scope for this user in the API. For me, the only person who can really be classified as malicious is someone who can steal an access token containing an administration area. That's why API developers are allowed to specify which areas to provide to the client, and if this is the first member application that uses something like a Password Grant, then as a user you have no choice but to trust him with your data.

I don’t know how to do this and use the extracted token inside another mobile application, but if you tried to manually request a token with an administration area, then I really don’t see anything bad (except you give the application more control with you, as a user context, therefore can it even be productive?)

If you need more control, then you need to go past your API and create something like application-level permissions for each user inside your resource server.

0
source share

All Articles