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

Adding well-known configuration and JWKS routes in Laravel #16

Merged
merged 3 commits into from
Apr 25, 2024

Conversation

moufmouf
Copy link
Collaborator

When using Laravel with Passport, we have enough knowledge of the environment
to be able to provide 2 useful routes our of the box:

  • a discovery endpoint at /.well-known/openid-configuration.
  • a JWKS endpoint at /oauth/jwks.

This greatly eases integrating with Laravel since clients can now
use auto-discovery to integrate with Laravel + PassPort + OpenID.

This PR has been successfully tested using the Javascript openid-client package.
This PR is based on top of #13

@moufmouf moufmouf changed the title Adding well-known configuration and JWT routes in Laravel Adding well-known configuration and JWKS routes in Laravel Jan 18, 2024
@mrmstn
Copy link

mrmstn commented Feb 5, 2024

I would be very interested in this PR, is there something left to do @ronvanderheijden? Or is there any case I could help bringing this PR forward?

@theaungmyatmoe
Copy link

I don't think the owner will make this PR forward, will you guys make this own community repo?

@moufmouf
Copy link
Collaborator Author

@aungmyatmoethegreat I will as a last resort. Before taking such steps, we should ask the repo owner if he needs some help. Maybe he saw the PRs but has no time to deal with those. I opened an issue to ask here: #21

@@ -35,26 +35,25 @@ public function boot()
__DIR__ . '/config/openid.php' => $this->app->configPath('openid.php'),
], ['openid', 'openid-config']);

$this->loadRoutesFrom(__DIR__.'/routes/web.php');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only add the routes when the setting is enable in the config.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I added in the config a routes entry and one can now select which routes should be enabled (I put the conditions in the web.php file)

Comment on lines 2 to 3
Route::get('/oauth/jwks', \OpenIDConnect\Laravel\JwksController::class."@jwks")->name('openid.jwks');
Route::get('/.well-known/openid-configuration', \OpenIDConnect\Laravel\DiscoveryController::class."@discovery")->name('openid.discovery');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Route::get('/oauth/jwks', \OpenIDConnect\Laravel\JwksController::class."@jwks")->name('openid.jwks');
Route::get('/.well-known/openid-configuration', \OpenIDConnect\Laravel\DiscoveryController::class."@discovery")->name('openid.discovery');
use OpenIDConnect\Laravel\JwksController;
use OpenIDConnect\Laravel\DiscoveryController;
Route::get('/oauth/jwks', [JwksController::class, 'jwks'])->name('openid.jwks');
Route::get('/.well-known/openid-configuration', [DiscoveryController::class, 'discovery'])->name('openid.discovery');

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But an __invoke() is perhaps a better improvement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go for the __invoke!


class DiscoveryController
{
public function discovery(Request $request)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use an invocable controller while calling a single method?

Suggested change
public function discovery(Request $request)
public function __invoke(Request $request)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@@ -21,15 +21,18 @@ class IdTokenResponse extends BearerTokenResponse
protected ClaimExtractor $claimExtractor;

private Configuration $config;
private ?string $issuer;

public function __construct(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use constructor property promotion in PHP 8.0. So that we can combine class fields, constructor definition and variable assignments all into one syntax, in the construct parameter list.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package is still compatible with PHP 7.4 (that's what is declared in composer.json) so I guess this is a no go for this version at least.

}

private function getPublicKey(): string {
$publicKey = str_replace('\\n', "\n", app()->make(Config::class)->get('passport.public_key') ?? '');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Larvel 11, config/passport.php is not published by default, so that we might use passport keypart to retieve the public key.

Suggested change
$publicKey = str_replace('\\n', "\n", app()->make(Config::class)->get('passport.public_key') ?? '');
$publicKeyFile = File::get(Passport::keyPath('oauth-public.key'));
$publicKey = str_replace('\\n', "\n", $publicKeyFile);

Copy link
Collaborator Author

@moufmouf moufmouf Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The public key file is not necessarily a file. It can come from env vars for instance. And I believe the config method will still read from the config file of teh package (even if the config is not published)

moufmouf and others added 3 commits April 24, 2024 11:14
When using Laravel with Passport, we have enough knowledge of the environment
to be able to provide 2 useful routes our of the box:

- a discovery endpoint at `/.well-known/openid-configuration`.
- a JWKS endpoint at `/oauth/jwks`.

This greatly eases integrating with Laravel since clients can now
use auto-discovery to integrate with Laravel + PassPort + OpenID.
Routes can now be disabled from the config.
Also, switching to using invokable routes.
@moufmouf
Copy link
Collaborator Author

@ronvanderheijden Thanks a lot for the review. I took your comments (and those of @aungmyatmoethegreat) in consideration and pushed the change. Tell me if it looks good. I'll rebase the other PRS depending on this one to apply the changes to all depending PRs.

Copy link

@theaungmyatmoe theaungmyatmoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@moufmouf
Copy link
Collaborator Author

Ok, let's merge this! 👍

@moufmouf moufmouf merged commit 9f56cce into ronvanderheijden:main Apr 25, 2024
@moufmouf moufmouf deleted the autodiscovery branch April 25, 2024 08:20
@ronvanderheijden
Copy link
Owner

This pull-request breaks the actions. I have fixed them in pull-requests #23 :)

@moufmouf
Copy link
Collaborator Author

Hey @ronvanderheijden,

Really sorry about that. I did not notice the actions. For some reason, they did not show up in the pull request on my side. I'll double check for the other PRs!

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.

5 participants