Lessons Learned & Practical Advice for Developers from my implemented Web App
Real-world insights from integrating an external IdP into a legacy PHP ecosystem—and what developers should know before building their own auth system

Series: Web Authentication Demystified — From Concepts to Real-World
ARC 2 — APPLYING THE THEORY: MY REAL IMPLEMENTATION
Previous: Security Analysis of my implemented Web App Authentication System
After exploring authentication from fundamentals to architecture to deep dive and security analysis, we’ve reached the final chapter of this series—a reflection on what actually happens when theory meets reality. Building a production authentication system that integrates a government IdP, a legacy-friendly PHP framework, Redis sessions, and CloudFront might look straightforward on paper, but real-world constraints introduce nuance that textbooks rarely address.
This article captures the lessons learned from implementing the CSL authentication system, what went smoothly, what proved unexpectedly tricky, and the practical guidance I’d give to teams attempting similar integrations. And finally, if I had the chance to redesign the system today, what I would refine or modernize.
Disclaimer
The articles in this current arc are based on a real authentication system I integrated and implemented for a government education department. Due to the Non-Disclosure Agreement (NDA) between myself and the client, certain internal details, configurations, and architectural specifics have been intentionally generalized or omitted. All explanations focus on the conceptual and technical patterns rather than sensitive operational information. I’ve made every effort to describe the system as accurately as possible while fully respecting confidentiality and security requirements.
1. Why Real Systems Rarely Match Textbook Examples
In documentation and academic diagrams, OAuth2 and OIDC look clean, predictable, and linear.
Reality, however, brings:
legacy frameworks
existing permission systems
organizational boundaries
CDN requirements
evolving IdP capabilities
security policies
infrastructure constraints
Most systems don’t get to start from scratch. They must absorb authentication, not reinvent it.
In CSL’s case:
HumHub/Yii uses server-managed PHP sessions
Government IdP dictates the authentication process
CloudFront must enforce access to protected assets
The application requires its own user model and permissions
The system must work across many browsers and devices
No tokens may be exposed to the frontend

This is why the final architecture became a hybrid design rather than a “pure OIDC” implementation. Real systems adapt patterns to context, not the other way around.
2. What Went Well

✔ External IdP Integration
Delegating authentication to the government IdP brought immediate benefits:
No password management in the app
Built-in MFA
Strong identity proofing
Standard OAuth2/OIDC flows
Identity assurance became someone else’s well-maintained responsibility.
✔ Redis Session Strategy
Redis-backed PHP sessions were:
fast
scalable
easy to invalidate
perfectly aligned with HumHub
This gave the app centralized control over login state without token exposure.
✔ User Provisioning Model
The user_auth mapping table worked smoothly:
stable matching via IdP
subclaimsgraceful handling of first-time users
clear boundary between IdP identity and application identity
✔ CloudFront Secured via Signed Cookies
Protecting static assets through short-lived CloudFront cookies delivered strong security with minimal complexity.
✔ Hybrid Flow Simplicity
The combination of:
OIDC identity
backend-only tokens
PHP session
resulted in a clean and secure integration with minimal risk of token leakage.
3. What Was Tricky
Session Handling Across Redirects
OIDC depends on short-lived browser redirects, but PHP sessions weren’t designed with OAuth2’s back-and-forth dance in mind. Ensuring session integrity during state and code exchange required careful orchestration.
User Provisioning Edge Cases
Mapping IdP identities to internal users uncovered corner cases:
disabled accounts
incomplete profile data
reassigning identities
teachers moving departments
These are the kinds of scenarios that specs never mention but real organizations always have.
CloudFront Cookie Generation
AWS signed cookie generation isn’t complex, but coordinating:
policy creation
key rotation
expiration windows
integration with app login
took thoughtful design to avoid fragile behavior.
No Tokens in the Browser
This improved security but required:
backend-only flow
no ID tokens for frontend rendering
careful handling of redirects and session regeneration

A “simple design decision” cascades into dozens of implementation details.
4. Advice for Teams Integrating an External IdP Into Legacy or Session-Based Systems

Start with identity mapping
Before technical implementation, answer:
How will an external identity link to an internal user?
Define the mapping early, whether via:
subemail
employee ID
or custom claims
Treat the IdP as the source of identity, not authorization
Let the IdP authenticate the user.
Let your app decide what they’re allowed to do.
Avoid exposing tokens to the frontend unless absolutely necessary
Legacy systems were never designed for browser-held JWTs.
A backend-only flow avoids:
XSS token theft
debugging complexity
refresh token storage issues
Don’t force a “textbook” OIDC implementation onto a legacy environment
Frameworks like PHP/Yii were built for stateful sessions.
Use that strength instead of fighting against it.
Prioritize secure cookies
Make them:
HttpOnly
Secure
SameSite=Lax/Strict
This single decision prevents entire classes of vulnerabilities.
Use the IdP for authentication, but retain permission control locally
Organizations evolve faster than identity claims do.
Log everything
Successful logins, failures, provisioning, CloudFront cookie issuance—log it.
Audit trails are invaluable for debugging and compliance.
5. If I Were to Redesign It Today
The system is robust, secure, and appropriate for its context—but there are modern refinements worth considering:
PKCE for completeness
Even though server-side apps don’t require PKCE, some modern IdPs enforce or recommend it.
Use ID tokens more extensively
Currently the access token is the main validated artefact.
Adopting ID tokens can standardize claim parsing and add nonce verification.
Refresh token rotation (for backend → IdP communication)
Would improve security for long-lived backend tasks.
Structured audit logging
A modern audit service (e.g., OpenSearch, CloudWatch, Elasticsearch index) would make operations smoother.
mTLS between CSL and IdP (if supported)
Provides strong service authentication in regulated environments.
CloudFront key rotation automation
To streamline signed cookie lifecycle management.

Each change is evolutionary, not revolutionary—the core architecture is sound.
Final Thoughts
If this series demonstrates anything, it’s that real-world authentication systems are a mosaic of constraints, protocols, legacy decisions, and modern security practices. The CSL system didn’t follow a perfect textbook blueprint; it followed the realities of PHP architecture, government IdP requirements, CDN constraints, and operational needs. And despite that, or perhaps because of it, the final implementation is stable, secure, and maintainable.
Thank you for following this journey—from core concepts, to tokens, to OAuth and OIDC, to flow design, hybrid architecture, and now the closing lessons. If this series helps even one developer approach identity integration with more clarity and confidence, it’s already a success.
With the core series complete, we can shift from concepts and architecture into hands-on, practical deep dives. For those who want to explore the implementation details behind the system, the optional bonus articles will walk through topics like building an OIDC callback in PHP/Yii/HumHub, understanding CloudFront signed cookies, designing Redis-backed session storage, and comparing OAuth2, OIDC, and SAML in real scenarios. If you’re ready to go deeper into the mechanics behind the ideas, the next articles are for you.
➤ Implementing an OIDC Callback in PHP/Yii/HumHub (with code examples)
➤ CloudFront Signed Cookies — How They Work and Why We Used Them






