Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.x] Add new EnsureClientIsResourceOwner middleware #1794

Merged

Conversation

hafezdivandari
Copy link
Contributor

@hafezdivandari hafezdivandari commented Oct 9, 2024

This PR does:

  • Fixes Client credentials are not secure for documented use case #691 by adding new EnsureClientIsResourceOwner middleware to make sure the token is a client_credentials token, as this comment asks for.
  • Merge the CheckForAnyScope middleware into CheckTokenForAnyScope middleware, as they have the same functionality.
  • Merge the CheckScopes middleware into CheckToken middleware, as they have the same functionality.
  • Improve the ValidateToken abstract class to be used for any other custom usages the developers may need.
  • Add Feature tests for 'Client Credentials" grant.

Summary

  • CheckScopes -> CheckToken
  • CheckForAnyScope -> CheckTokenForAnyScope
  • New EnsureClientIsResourceOwner

Usage

Refer to the updated docs.

Example

You may define middleware aliases in your application's bootstrap/app.php file:

use Laravel\Passport\Http\Middleware\CheckClientCredentials;
 
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'token' => CheckToken::class,
        'scopes' => CheckToken::class,
        'scope' => CheckTokenForAnyScope::class,
        'client' => EnsureClientIsResourceOwner::class,
    ]);
})

And use them like:

Route::get('/orders', function (Request $request) {
    // Access token is valid...
})->middleware('token');

Route::get('/orders', function (Request $request) {
    // Access token is valid and has both "check-status" and "place-orders" scopes...
})->middleware('token:check-status,place-orders');

Route::get('/orders', function (Request $request) {
    // Access token is valid and has both "check-status" and "place-orders" scopes...
})->middleware('scopes:check-status,place-orders');

Route::get('/orders', function (Request $request) {
    // Access token is valid and has either "check-status" or "place-orders" scope...
})->middleware('scope:check-status,place-orders');

Route::get('/orders', function (Request $request) {
    // Access token is valid and the client is the resource owner (`client_credentials` grant type)...
})->middleware('client');

Route::get('/orders', function (Request $request) {
    // Access token is valid, the client is the resource owner, and has both "check-status" and "place-orders" scopes...
})->middleware('client:check-status,place-orders');

Route::get('/orders', function (Request $request) {
    // Access token is valid, the client is the resource owner, and has both "check-status" and "place-orders" scopes...
})->middleware(['client', 'scopes:check-status,place-orders']);

Route::get('/orders', function (Request $request) {
    // Access token is valid, the client is the resource owner, and has either "check-status" or "place-orders" scopes...
})->middleware(['client', 'scope:check-status,place-orders']);

Route::get('/orders', function () {
    // The user is authenticated and has both "check-status" and "place-orders" scopes...
})->middleware(['auth:api', 'scopes:check-status,place-orders']);

Route::get('/orders', function () {
    // The user is authenticated and has either "check-status" or "place-orders" scope...
})->middleware(['auth:api', 'scope:check-status,place-orders']);

Copy link

github-actions bot commented Oct 9, 2024

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@hafezdivandari hafezdivandari marked this pull request as ready for review October 9, 2024 18:20
@taylorotwell
Copy link
Member

What does ensuring the client is the resource owner actually mean / do? What resource?

@hafezdivandari
Copy link
Contributor Author

hafezdivandari commented Oct 9, 2024

@taylorotwell the "resource" is protected by the token. This new middleware ensures that the resource owner is an OAuth client itself and not any user with valid token. When issuing an access token using "Client Credentials" grant, the oauth_client_id (JWT's aud) is the same as oauth_user_id (JWT's jti) unlike any other grants. Refer to RFC 6749 section 1.3.4:

The client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client, or to protected resources previously arranged with the authorization server. Client credentials are used as an authorization grant typically when the client is acting on its own behalf (the client is also the resource owner) or is requesting access to protected resources based on an authorization previously arranged with the authorization server.

@taylorotwell taylorotwell merged commit 6fafccc into laravel:13.x Oct 9, 2024
4 checks passed
@hafezdivandari hafezdivandari deleted the 13.x-client-resource-owner branch October 9, 2024 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants