Download the PHP package uadevteampackages/imitator without Composer
On this page you can find all versions of the php package uadevteampackages/imitator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download uadevteampackages/imitator
More information about uadevteampackages/imitator
Files in uadevteampackages/imitator
Package imitator
Short Description Local-only Entra user imitation for Laravel apps
License MIT
Informations about the package imitator
UA Laravel Imitator
Local-only Entra user imitation for Laravel applications. Search Microsoft Graph, log in as the selected user, and restore your original session when you stop — without leaving leftover imitated state behind.
Requirements
- PHP 8.2+
- Laravel 12 or 13
IMITATOR_ENABLED=trueand anAPP_ENVthat does not start withprod(case-insensitive) — otherwise the package stays inert- A Laravel auth guard user (
Auth::check()/Auth::user()) — session-only OIDC withoutAuth::login()is not enough - An Entra app registration with application permission to search users (typically
User.Read.All)
Quick Start
1. Install the package
Until a stable release is tagged, require the RC with an explicit stability flag (most Laravel apps use "minimum-stability": "stable", which will reject a bare composer require):
After a stable v0.1.0 (or later) is published, this will work instead:
2. Publish the config
3. Add your Entra credentials to .env
If your app has no route('login') (for example Okta OIDC), also set:
4. Open the imitator UI
Sign in to your app as usual (so Auth::user() is populated), then visit:
Search for an Entra user, start imitation, use the app as that user, then stop from the banner or the imitator page.
That's it for UA-shaped user models (string Entra object id as the primary key). If your users table uses auto-increment ids, see Authentication.
How It Works
Starting (or switching) imitation
- You must already be authenticated via Laravel's auth guard (
Auth::user()) - You select an Entra user from Graph search
- The package upserts a local user from the Graph payload using your configured attribute map
- On the first start in a session, it snapshots the entire current session (except the imitator bag)
- It applies a clean slate (keeps the CSRF token), then
Auth::login()as the target user - You are redirected to
/
If you start imitation again while already imitating, the original snapshot is kept. Only the target user changes.
Stopping imitation
- The package restores the snapshotted session
- It logs you back in as the original user
- It clears the imitator session bag
- You are redirected to
/imitator
Routes
Routes register only when the package is enabled (IMITATOR_ENABLED=true and APP_ENV does not start with prod), under the imitator prefix. Default middleware is web, imitator.auth, and imitator.local (configurable via imitator.middleware):
| Method | URI | Name | Purpose |
|---|---|---|---|
GET |
/imitator |
imitator.index |
Selection UI |
GET |
/imitator/search |
imitator.search |
Graph user search (JSON) |
POST |
/imitator |
imitator.store |
Start or switch imitation |
DELETE |
/imitator |
imitator.destroy |
Stop and restore original session |
Authentication
Imitator requires a real Laravel auth user (Auth::user()), not only an OIDC session bag.
imitator.auth checks the default guard. Unauthenticated guests are redirected to:
config('imitator.redirect_guests_to')when set, otherwiseroute('login')when that route exists, otherwise- HTTP
401
Apps with a login route
No extra config — the fallback to route('login') is enough.
Okta OIDC hosts (ua/okta-oidc)
-
Point guests at the OIDC login path:
-
Use a bootstrapper that calls
Auth::login(), such asEloquentUserBootstrapper. Session-only bootstrappers leaveAuth::user()empty, so/imitatorwill keep treating you as a guest. - Optionally rewrite Okta session keys while imitating — see Session attributes.
User Mapping
When imitation starts, Graph user data is written to a local Eloquent model. Defaults match the UA Entra user shape. Override config/imitator.php for other schemas.
Attribute sources
| Source key | Meaning |
|---|---|
id |
Entra object id |
name |
Display name |
email |
Mail, falling back to userPrincipalName when empty |
userPrincipalName |
Full UPN |
job_title |
Job title (nullable) |
username |
Lowercased local-part of the UPN (before @) |
unique_by is the local column used to find or create the user. Self-imitation is rejected by comparing that same key.
UA-shaped users (default)
String primary key = Entra object id, plus principal_name / username / job_title:
Or via environment:
Standard auto-increment users (match by email)
create_only attributes are set only when creating a new row. Use 'random' to generate a random string — if your model casts password as hashed, pass plain 'random' and let the cast hash it.
Banner
While imitation is active, HTML responses get an imitating banner injected after <body> by default, including a Stop control.
Disable injection and place the banner yourself:
Publish views if you want to customize them:
Session Behavior
| Phase | Behavior |
|---|---|
| First start | Full session snapshot stored under imitator.snapshot (imitator bag excluded) |
| While imitating | Clean slate session + imitator metadata + target auth; CSRF _token preserved |
| Switch target | Original snapshot unchanged; clean slate again; login as new target |
| Stop | Snapshot restored; original user logged back in; imitator.* cleared |
This is the main difference from packages that exit proxy mode by flushing the session and forcing a full logout.
Session attributes (optional)
Some host apps identify the current user with session keys (for example session('username') from ua/okta-oidc) instead of Auth::user(). Configure imitator.session to rewrite those keys on start/switch:
| Source | Behavior |
|---|---|
Entra sources (id, name, email, userPrincipalName, username, job_title) |
Resolved from the Graph payload used to start imitation |
okta_principal |
Calls config('okta-oidc.principal_resolver') with Entra UPN mapped to preferred_username (stays in sync with Okta login) |
preserve |
Copies that session key from the original snapshot (useful for Okta expiry) |
expires_at |
Sets now + session_expires_in seconds as an ISO-8601 timestamp |
Stopping imitation restores the snapshotted session, so original keys come back automatically.
Graph Search Filters
Search uses client credentials against Microsoft Graph. Results are filtered with UA defaults:
| Filter | Default |
|---|---|
| Exclude job titles | STUDENT |
| Exclude UPN suffixes | @bama365.onmicrosoft.com |
| Exclude UPN prefixes | oit-, edas-, admin-, cs-, iam- |
Override in config:
Set a list to [] to disable that filter category.
Configuration Reference
Publish with php artisan vendor:publish --tag=imitator-config.
| Key | Default | Description |
|---|---|---|
enabled |
env('IMITATOR_ENABLED', false) |
Must be true to register routes/banner; still inert if APP_ENV starts with prod |
user.model |
env('IMITATOR_USER_MODEL', 'App\\Models\\User') |
Eloquent user model |
user.unique_by |
env('IMITATOR_USER_UNIQUE_BY', 'id') |
Local column used to find/create the user |
user.attributes |
UA Entra map (see above) | Local column → Entra source key |
user.create_only |
[] |
Attributes set only on create ('random' supported) |
session |
[] |
Session key → source written after clean slate on start/switch |
session_expires_in |
env('IMITATOR_SESSION_EXPIRES_IN', 28800) |
Seconds used by the expires_at session source |
middleware |
['web', 'imitator.auth', 'imitator.local'] |
Middleware stack for imitator routes |
redirect_guests_to |
env('IMITATOR_REDIRECT_GUESTS_TO') |
Guest redirect URL; falls back to route('login') |
inject_banner |
env('IMITATOR_INJECT_BANNER', true) |
Auto-inject imitating banner into HTML responses |
azure.tenant_id |
env('IMITATOR_AZURE_TENANT_ID') |
Entra tenant id |
azure.client_id |
env('IMITATOR_AZURE_CLIENT_ID') |
App registration client id |
azure.client_secret |
env('IMITATOR_AZURE_CLIENT_SECRET') |
App registration client secret |
graph_filters.exclude_job_titles |
['STUDENT'] |
Job titles excluded via $filter |
graph_filters.exclude_upn_suffixes |
['@bama365.onmicrosoft.com'] |
UPN suffixes dropped from results |
graph_filters.exclude_upn_prefixes |
['oit-', 'edas-', …] |
UPN prefixes dropped from results |
Security Notes
- The package only registers routes and banner middleware when
IMITATOR_ENABLED=trueandAPP_ENVdoes not start withprod(case-insensitive, e.g.production,prod,Prod). Otherwise it stays inert. - Install as
require-devonly. Never ship this to shared test or production environments. - Graph credentials use the client credentials flow. The Entra app needs permission to read/search users (typically application
User.Read.All), granted admin consent. - There is no admin Gate. Any authenticated Laravel user (
Auth::check()) in an enabled non-prod app with this package installed can start and stop imitation. - Stopping imitation restores the original session snapshot; it does not depend on the target user remaining an admin.
All versions of imitator with dependencies
illuminate/auth Version ^12.0|^13.0
illuminate/contracts Version ^12.0|^13.0
illuminate/http Version ^12.0|^13.0
illuminate/routing Version ^12.0|^13.0
illuminate/session Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/view Version ^12.0|^13.0