1. Go to this page and download the library: Download bbs-lab/laravel-okta library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
return [
// The URI each Okta route mounts at, relative to the panel's route prefix.
// 'login' is where your Okta button points (it starts the redirect to Okta);
// 'callback' is the OIDC redirect_uri you whitelist in Okta. The route names
// never change, so route() callers are unaffected. For Filament, set these
// per panel with OktaPlugin::make()->paths(...) instead.
'paths' => [
'login' => env('OKTA_LOGIN_PATH', 'authorization-code/redirect'),
'callback' => env('OKTA_CALLBACK_PATH', 'authorization-code/callback'),
'logout' => env('OKTA_LOGOUT_PATH', 'authorization-code/logout'),
'callback_logout' => env('OKTA_CALLBACK_LOGOUT_PATH', 'authorization-code/callback/logout'),
],
// Logout also ends the Okta session (OIDC end-session / single sign-out).
// false = clear only the local session, leave the Okta session alone.
'sso_logout' => env('OKTA_SSO_LOGOUT', true),
// Reject a login whose Okta email is not verified (OIDC email_verified claim).
// Guards against the email-based account-takeover class. Disable only if your
// Okta org never sends email_verified.
'
use BBSLab\LaravelOkta\Facades\Okta;
// Decide WHO may sign in — this is the primary gate. Every callback must return
// true; return false to deny. Runs on top of the default resolver, keeping the
// verified-email check and the stable-id matching below.
Okta::authorizeUserToLogin(fn ($user, $oktaUser) => $user->is_active);
// Side effects around login.
Okta::beforeLogin(fn ($user, $oktaUser) => /* ... */);
Okta::afterLogin(fn ($user, $oktaUser) => $user->forceFill(['logged_at' => now()])->save());
// Audit a refused login (user not resolved, or an authorize callback denied it).
Okta::onLoginDenied(fn ($user, $oktaUser) => Log::warning('Okta login denied', ['email' => $oktaUser->getEmail()]));
'identifier' => [
'column' => 'okta_id', // or 'provider_id', etc.; null = match by email only
'update' => true, // backfill the column on the first (verified) email match
],
use BBSLab\LaravelOkta\Contracts\OktaUserResolver;
$this->app->bind(OktaUserResolver::class, GatedOktaUserResolver::class);
use BBSLab\LaravelOkta\Resolvers\DefaultOktaUserResolver;
use Illuminate\Contracts\Auth\Authenticatable;
use Laravel\Socialite\Contracts\User as OktaUser;
class GatedOktaUserResolver extends DefaultOktaUserResolver
{
/** The one thing that varies per project. */
protected array $allowedRoles = ['root', 'admin'];
public function resolve(OktaUser $oktaUser): ?Authenticatable
{
// Reuse the base lookup (verified email + stable-id matching + backfill)...
$user = parent::resolve($oktaUser);
// ...then apply the shared gate. Never create a user.
if (! $user
|| ! $user->getAttribute('is_sso_allowed')
|| ! in_array($user->getAttribute('role'), $this->allowedRoles, true)) {
return null;
}
return $user;
}
}
use BBSLab\LaravelOkta\Support\ConfigOktaPanel;
use Illuminate\Http\Request;
class MyPanel extends ConfigOktaPanel
{
public function guard(): ?string { return 'admin'; } // null = auth.defaults.guard
public function loginUrl(): string { return route('admin.login'); }
public function homeUrl(Request $request): string { return url('/admin'); }
public function routePrefix(): string { return 'admin'; } // URI prefix, or '' for root
public function routeName(): string { return 'my-okta'; } // {name}.login, {name}.callback, …
public function middleware(): array { return ['web']; }
}
use BBSLab\LaravelOkta\Contracts\OktaPanel;
use BBSLab\LaravelOkta\Support\OktaRoutes;
$this->app->bind(OktaPanel::class, MyPanel::class);
OktaRoutes::register($this->app->make(OktaPanel::class));