zetacomponents/mvc-authentication-tiein
Zeta Components MVC Authentication Tie-In wires the Authentication component into the MVC stack, adding filters that protect controllers and routes. Part of the legacy Apache Zeta Components project, so verify maintenance status and PHP version support before adopting.
Reality check first. zetacomponents/mvc-authentication-tiein is a glue package from the eZ Components / Zeta Components era (PHP 5.x, last meaningful activity circa 2011). It is not a framework — it is essentially one filter class that plugs the Authentication component into the MvcTools dispatcher. Treat it as ~150 lines of reference code you may end up vendoring rather than a dependency you own. 3 stars and 0 dependents means no community to fall back on.
Install (and expect friction).
composer require zetacomponents/mvc-authentication-tiein \
zetacomponents/mvc-tools \
zetacomponents/authentication \
zetacomponents/base
Pin exact versions rather than floats — the published packages are old and their constraints are loose. On PHP 8 you will almost certainly need --ignore-platform-reqs and should still expect deprecation noise or hard failures (each(), old-style constructors, create_function-era idioms in transitive deps).
Bootstrap. eZ Components ship their own autoloader (ezcBase::autoload), not just PSR-0/4. Confirm it is registered before you touch any ezc* class — check vendor/zetacomponents/base/src/base.php and the autoload.php at the root of the tie-in package. If the Composer metadata does not wire that up for you, require it manually in your bootstrap, ahead of vendor/autoload.php for the eZ classes.
Where to look, in order:
src/filter.php — the entire component lives here (ezcMvcAuthenticationFilter).src/options.php — ezcMvcAuthenticationFilterOptions; this is your real API surface (login action, logout action, which request variables get populated, etc.). Read it before writing any integration code.vendor/zetacomponents/mvc-tools/src/config.php — ezcMvcConfig::addPreFilter() is the hook you will use.vendor/zetacomponents/authentication/src/session/ — ezcAuthenticationSession, which is what makes the filter cheap on every request.First use case — gate the whole app except login/logout:
$config = new ezcMvcConfig();
// ... your routing rules, views, request parser ...
$options = new ezcMvcAuthenticationFilterOptions();
$options->loginAction = 'login'; // route/action name the filter redirects to
$options->logoutAction = 'logout';
// remaining knobs: see src/options.php in the package
$config->addPreFilter( new ezcMvcAuthenticationFilter( $options ) );
$dispatcher = new ezcMvcDispatcher( $config );
$dispatcher->run();
Smoke test: with no session, request a protected URL and confirm a redirect to the login action and no redirect loop. Then log in and confirm the same URL renders. That covers 90% of what this package does.
Pre-filter, not middleware. The filter fires before routing/controller dispatch on every request. It does not route, does not render, and does not own credentials. Everything it can express is "if not authenticated, redirect to loginAction."
Two-phase authentication. This is the pattern the component is built for, and the one to copy even if you rewrite it:
ezcAuthenticationSession. No database, no LDAP.ezcAuthentication plus one or more authentication filters (database, LDAP, etc.).class LoginController extends ezcMvcController
{
public function doLogin()
{
$credentials = new ezcAuthenticationPasswordCredentials(
$this->request->body['username'] ?? '',
$this->request->body['password'] ?? ''
);
$auth = new ezcAuthentication( $credentials );
$auth->addFilter( new ezcAuthenticationDatabaseFilter( $dbOptions ) );
$session = new ezcAuthenticationSession();
$session->start();
// Method names vary between releases — verify against
// vendor/zetacomponents/authentication/src/session/.
if ( $auth->run() && $session->isValid() ) {
$session->save();
return $this->redirectTo( '/' );
}
return new ezcMvcResult(); // render the login view with an error flag
}
}
Exempting routes. The filter only knows about loginAction/logoutAction. Everything else is protected. If you need public routes (registration, password reset, health checks, static assets), wrap the filter in a thin subclass or a pre-filter that short-circuits on the request URI before delegating. Do not try to express this in the options object — it will not fit.
Expose the user to controllers. Use the filter's variable mapping so controllers read the identity from $request->variables instead of re-querying the session in every action. That single decision keeps your controllers testable.
Ordering with other pre-filters. If you have a pre-filter that starts the session, normalises the request, or handles CORS, register it before the authentication filter. Otherwise ezcAuthenticationSession has nothing to read.
Logout. Either a dedicated logoutAction controller that calls the session's destroy path and then redirects, or a post-filter that scrubs state on the way out. The controller is easier to reason about and easier to test.
In a Laravel/Symfony/Slim codebase. Don't force this package in. The entire behaviour is:
// conceptually, in Laravel middleware terms
if (! Auth::check() && ! $request->routeIs('login', 'logout')) {
return redirect()->route('login')->with('intended', $request->fullUrl());
}
That is the real deliverable here — port the shape, not the dependency. If you are already on Laravel, you get this for free with the auth middleware plus Auth::attempt() and $request->session()->regenerate(), and you get maintained code and security patches. Only adopt the eZ package if you are actually standing up an ezcMvcDispatcher.
Testing. Because the filter takes an options object and operates on ezcMvcRequest, you can unit-test it by constructing a request with/without a populated session and asserting on the result (redirect vs. pass-through). Do this before you build anything on top of it — it is the fastest way to discover what your installed version's API actually looks like.
Maintenance and license. NOASSERTION on license means the metadata does not cleanly declare terms — read LICENSE, docs/, and file headers in the repo before shipping. Regardless of license, this is unmaintained code with 0 dependents and 3 stars; assume you are the maintainer from day one. If you cannot afford to vendor and patch it, do not depend on it.
PHP 8 will hurt. Old eZ Components code predates modern typing, uses loose comparisons, and relies on its own autoloader conventions. Run the full dependency tree under your target PHP version first, on a scratch branch, before writing a line of integration code.
Infinite redirect loops. The classic failure: the login action is itself behind the filter. Verify the login and logout action names match exactly what your router produces (spacing, casing, leading slash). A mismatch is silent — you get a 302 loop, not an error.
Session start ordering. ezcAuthenticationSession needs a session, and sessions need to start before output. If anything echoes, sets a cookie, or emits headers before the pre-filter runs, authentication silently fails and users bounce back to login forever.
Per-request cost. The filter runs on every request, including asset and 404 requests. Make sure the cheap path really is cheap — a session start per static file will show up as latency under load.
Filter ordering is not declarative. addPreFilter() ordering is call order. There is no priority system. Document the order in a comment at the registration site; future-you will not remember.
Debugging. The filter has no logging or diagnostics. Drop a temporary pre-filter immediately after it that dumps $request->variables and the session state, and remove it once things work. That is faster than reading the dispatcher source to figure out why a route passed or failed.
Extension points, ranked by effort:
ezcMvcPreFilter implementations registered around it (allowlists, logging, session bootstrapping).ezcMvcAuthenticationFilter to add route exclusions.ezcMvcPreFilter yourself against ezcAuthentication — usually ~30 lines and far easier to debug than an unmaintained dependency.One last sanity check. Before adopting, diff src/filter.php against what you actually need. If your requirement is "redirect to login when the session is empty," you are about to take on an abandoned PHP 5 dependency for something you could write, test, and own before lunch.
How can I help you explore Laravel packages today?