Internship · Mobilis · Summer 2026 Stage · Mobilis · Été 2026تربص · موبيليس · صيف 2026

Single sign-on platformPlateforme d'authentification uniqueمنصة الدخول الموحَّد

Sign in once, access every application, each with its own roles. An OAuth2 / OpenID Connect server, an admin panel and a client that never lets a token reach the browser. Une seule connexion pour toutes les applications, chacune avec ses propres rôles. Un serveur OAuth2 / OpenID Connect, un panneau d'administration et un client qui ne laisse jamais un token arriver dans le navigateur.تسجيل دخول واحد لجميع التطبيقات، ولكل تطبيق أدواره الخاصة. خادم OAuth2 / OpenID Connect، ولوحة إدارة، وعميل لا يسمح أبداً بوصول أي رمز (token) إلى المتصفح.

TeamÉquipeالفريق
Adel Merad & Abdelhadi Deffous
ContextContexteالسياق
Internship, Development Department, MobilisStage, Direction du développement, Mobilisتربص في مديرية التطوير، موبيليس
StackStackالتقنيات
ASP.NET Core 8 · OpenIddict · ASP.NET Identity · EF Core · SQL Server · React · TypeScript
CodeCodeالشيفرة
ShopAuth ↗ · ShopWebApp ↗

01The goalL'objectifالهدف

When every internal application manages its own accounts, people end up with one password per app, and disabling someone means going through every app one by one. The goal was a single identity server: users sign in once, applications delegate authentication to it, and administrators manage accounts and roles in one place. Quand chaque application interne gère ses propres comptes, chacun finit avec un mot de passe par appli, et désactiver quelqu'un oblige à passer par toutes les applis une par une. L'objectif : un seul serveur d'identité. Les utilisateurs se connectent une fois, les applications lui délèguent l'authentification, et les administrateurs gèrent comptes et rôles au même endroit.عندما يدير كل تطبيق داخلي حساباته بنفسه، ينتهي الأمر بكلمة مرور لكل تطبيق، ويصبح تعطيل حساب شخص ما مروراً على التطبيقات واحداً تلو الآخر. الهدف: خادم هوية واحد. يسجّل المستخدمون دخولهم مرة واحدة، وتوكل التطبيقات إليه عملية المصادقة، ويدير المشرفون الحسابات والأدوار من مكان واحد.

02ArchitectureArchitectureالبنية

Architecture: browser, client app (BFF), SSO server, SQL Server and admin panel
  • SSO serverServeur SSOخادم SSO

    ASP.NET Core with OpenIddict and ASP.NET Identity. Signs users in and issues the tokens.ASP.NET Core avec OpenIddict et ASP.NET Identity. Connecte les utilisateurs et émet les tokens.ASP.NET Core مع OpenIddict و ASP.NET Identity. يتولى تسجيل دخول المستخدمين وإصدار الرموز (tokens).

  • Admin panelPanneau d'administrationلوحة الإدارة

    React and TypeScript, served by the SSO server under /admin. Applications, accounts, roles and suspensions.React et TypeScript, servi par le serveur SSO sous /admin. Applications, comptes, rôles et suspensions.React و TypeScript، يقدّمها خادم SSO عبر المسار ‎/admin. التطبيقات والحسابات والأدوار وتعليق الحسابات.

  • Client app (BFF)Application cliente (BFF)التطبيق العميل (BFF)

    A Backend-for-Frontend that runs the OpenID Connect sign-in and keeps the tokens on the server.Un Backend-for-Frontend qui fait la connexion OpenID Connect et garde les tokens côté serveur.خادم Backend-for-Frontend يتولى تسجيل الدخول عبر OpenID Connect ويحتفظ بالرموز في جهة الخادم.

  • Front endFrontالواجهة

    Handles no token at all: it only calls the BFF, and the browser sends the session cookie.Ne manipule aucun token : il appelle seulement le BFF, et le navigateur envoie le cookie de session.لا تتعامل مع أي رمز: تستدعي الـ BFF فقط، والمتصفح يرسل ملف تعريف الجلسة (cookie).

03Key decisionsChoix techniquesالخيارات التقنية

PKCE for every clientPKCE pour tous les clientsPKCE لجميع العملاء

Only the Authorization Code flow is enabled, and PKCE is mandatory, so a stolen authorization code is useless without the verifier. Seul le flux Authorization Code est activé, et PKCE est obligatoire : un code d'autorisation volé ne sert à rien sans le verifier.تدفق Authorization Code وحده مُفعَّل، و PKCE إلزامي: رمز التفويض المسروق لا فائدة منه دون الـ verifier.

No tokens in the browserAucun token dans le navigateurلا رموز في المتصفح

The BFF stores the tokens server-side. The browser only holds an HttpOnly cookie with an opaque session id. The id_token is checked against the SSO's JWKS keys: signature, issuer, audience and expiry. Le BFF garde les tokens côté serveur. Le navigateur n'a qu'un cookie HttpOnly avec un identifiant de session opaque. L'id_token est vérifié avec les clés JWKS du SSO : signature, émetteur, audience et expiration.يحتفظ الـ BFF بالرموز في جهة الخادم. لا يملك المتصفح سوى cookie من نوع HttpOnly يحمل معرّف جلسة غير قابل للقراءة. ويُتحقَّق من الـ id_token بمفاتيح JWKS الخاصة بالـ SSO: التوقيع، والجهة المُصدِرة، والجمهور، وتاريخ الانتهاء.

Rotation and proactive refreshRotation et renouvellement anticipéالتدوير والتجديد المُسبق

Refresh tokens are rotated on each use. The BFF renews the access token when it expires in under 60 seconds. An invalid refresh token closes the session; a network or SSO outage does not sign the user out. Les refresh tokens changent à chaque utilisation. Le BFF renouvelle l'access token quand il expire dans moins de 60 secondes. Un refresh token invalide ferme la session ; une panne réseau ou du SSO ne déconnecte pas l'utilisateur.تتغيّر رموز التحديث (refresh tokens) عند كل استعمال. يجدّد الـ BFF رمز الوصول عندما تبقى على انتهائه أقل من 60 ثانية. رمز تحديث غير صالح يُنهي الجلسة؛ أما عطل الشبكة أو الـ SSO فلا يُخرج المستخدم.

Roles per applicationDes rôles par applicationأدوار خاصة بكل تطبيق

Besides the global Admin role, each application declares its own roles: "Employee" in HR and "Employee" in Stock never interfere. An account with no role in an application is refused at sign-in. En plus du rôle global Admin, chaque application déclare ses propres rôles : « Employé » dans les RH et « Employé » dans le stock ne se mélangent jamais. Un compte sans rôle dans une application est refusé à la connexion.إلى جانب الدور العام Admin، يعرّف كل تطبيق أدواره الخاصة: دور « موظف » في الموارد البشرية ودور « موظف » في المخزون لا يختلطان أبداً. والحساب الذي لا يملك أي دور في تطبيق ما يُرفض عند تسجيل الدخول.

Admin safeguardsGarde-fous d'administrationضمانات الإدارة

The last administrator cannot be removed, an admin cannot lock themselves out, and accounts can be suspended until a date. A disabled or suspended account is checked again before any token is issued. Impossible de supprimer le dernier administrateur ou de se bloquer soi-même, et les comptes peuvent être suspendus jusqu'à une date. Un compte désactivé ou suspendu est revérifié avant l'émission de chaque token.لا يمكن حذف آخر مشرف ولا أن يُقفل المشرف حسابه بنفسه، ويمكن تعليق الحسابات إلى تاريخ محدد. ويُعاد التحقق من الحساب المعطَّل أو المعلَّق قبل إصدار كل رمز.

Secrets out of the codeLes secrets hors du codeالأسرار خارج الشيفرة

Connection strings, client secrets and the first admin password live in .NET user-secrets on each machine, never in the repository. Chaînes de connexion, secrets clients et mot de passe du premier admin vivent dans les user-secrets .NET de chaque machine, jamais dans le dépôt.سلاسل الاتصال وأسرار العملاء وكلمة مرور المشرف الأول تُحفظ في user-secrets الخاصة بـ ‎.NET على كل جهاز، وليس في المستودع أبداً.

04Admin panelPanneau d'administrationلوحة الإدارة

Screens with demo data.Écrans avec des données de démonstration.شاشات ببيانات تجريبية.

05What I learned, and what's nextCe que j'ai appris, et la suiteما تعلّمته، وما بعده

  • How OAuth2 and OpenID Connect really work, beyond calling a library: authorization codes, PKCE, token lifetimes, signature validation.Comment OAuth2 et OpenID Connect fonctionnent vraiment, au-delà d'une librairie : codes d'autorisation, PKCE, durée de vie des tokens, validation des signatures.كيف يعمل OAuth2 و OpenID Connect فعلاً، أبعد من مجرد مكتبة: رموز التفويض، و PKCE، ومدة صلاحية الرموز، والتحقق من التوقيعات.
  • Why the BFF pattern is the safer choice for web apps: the browser has nothing worth stealing.Pourquoi le pattern BFF est le choix le plus sûr pour une appli web : le navigateur n'a rien qui vaille la peine d'être volé.لماذا يُعدّ نمط BFF الخيار الأكثر أماناً لتطبيق ويب: لا يحتوي المتصفح على شيء يستحق السرقة.
  • Designing for failure: deciding when to close a session and when to keep the user signed in.Penser aux pannes : décider quand fermer une session et quand garder l'utilisateur connecté.التفكير في الأعطال: متى نُنهي الجلسة ومتى نُبقي المستخدم متصلاً.

Next steps: single logout across all applications at once, and applying role changes without waiting for the next sign-in. Pistes d'amélioration : une déconnexion unique sur toutes les applications à la fois, et la prise en compte d'un changement de rôle sans attendre la connexion suivante.تحسينات ممكنة: تسجيل خروج موحَّد من جميع التطبيقات دفعة واحدة، وتطبيق تغيير الدور دون انتظار تسجيل الدخول التالي.