wissen-sso-sdk-demo-public
v2.0.0
Published
Wissen SSO SDK — request and integrate Entra ID app registrations via the Identity Automation Platform
Maintainers
Readme
Wissen SSO SDK Platform
A Single Sign-On (SSO) management platform for registering, approving, and provisioning internal applications with SSO integration. Built with a React frontend, Express backend, MongoDB, and Keycloak for identity management.
Architecture
+------------------+
| Admin Approves |
| the App Request |
+--------+---------+
|
+----------------+ v +------------------+
| Developer |------->| Backend (Express) |------->| Identity Provider |
| (Frontend UI) |<-------| (Orchestration) |<-------| (Keycloak/Entra) |
+----------------+ +--------+-----------+ +------------------+
|
v
+------------+
| MongoDB |
| (Database) |
+------------+Services
| Service | Port | Description |
|---------|------|-------------|
| Frontend | 3000 | React + TypeScript + Vite developer portal |
| Backend | 8090 | Express API orchestration service |
| Keycloak | 8081 | Identity provider (OIDC/OAuth2) |
| MongoDB | 27017 | Database |
Port Configuration
All ports are defined in .env files for uniformity:
| Variable | File | Default |
|----------|------|---------|
| PORT | .env (root) | 8090 |
| PORTAL_PORT | .env (root) | 3000 |
| VITE_DEV_PORT | frontend/.env | 3000 |
| VITE_API_URL | frontend/.env | http://localhost:8090 |
| VITE_KEYCLOAK_URL | frontend/.env | http://localhost:8081 |
Project Structure
sso-sdk-wissen/
├── backend/ # Express API server
│ ├── src/
│ │ ├── index.js # Entry point, CORS, routes
│ │ ├── config/db.js # MongoDB connection
│ │ ├── middleware/
│ │ │ ├── auth.js # JWT validation (express-oauth2-jwt-bearer)
│ │ │ ├── errorHandler.js
│ │ │ └── roleGuard.js # Role-based access control
│ │ ├── models/ # Mongoose schemas
│ │ ├── routes/ # API route handlers
│ │ ├── services/ # Business logic
│ │ └── automation/ # IDP provisioning (mock)
│ ├── policies/ # Security policy templates
│ └── Dockerfile
├── frontend/ # React + TypeScript + Vite
│ ├── src/
│ │ ├── api/ # Axios client + API functions
│ │ ├── components/ # Shared UI components
│ │ ├── config/ # Keycloak & auth config
│ │ ├── hooks/ # React hooks
│ │ └── pages/ # Route pages
│ ├── .env # Frontend environment
│ ├── vite.config.ts
│ └── Dockerfile
├── sdks/
│ └── nodejs/ # Node.js SSO middleware SDK
│ └── src/index.js # authenticate(), requireRole(), protect()
├── infrastructure/
│ └── keycloak/
│ └── realm-export.json # Keycloak realm config
├── docker-compose.yml # Full-stack Docker setup
├── .env # Environment variables
├── .env.example # Template for .env
├── DIAGRAM.md # System architecture diagrams
├── EXPLAIN.md # In-depth project explanation
└── WORKFLOW.md # Build process documentationPrerequisites
- Node.js 20+
- Docker Desktop (for Keycloak, MongoDB, or full-stack Docker)
- npm
Quick Start (Local Dev)
1. Start Infrastructure (Docker)
Keycloak and MongoDB are required for the backend to function:
docker compose up -d keycloak mongoThis starts:
- Keycloak on
http://localhost:8081(realm:wissen) - MongoDB on
localhost:27017
2. Start Backend
cd backend
npm install
npm run devThe backend starts on http://localhost:8090.
Health check: http://localhost:8090/actuator/health
3. Start Frontend
cd frontend
npm install
npm run devThe frontend starts on http://localhost:3000.
4. Login Credentials
| User | Password | Role |
|------|----------|------|
| alice.admin | password | Admin |
| bob.developer | password | Developer |
| carol.hr | password | Approver |
Full-Stack Docker
Run everything in containers:
docker compose up -dThis starts all 4 services. The frontend is available at http://localhost:3000.
To stop:
docker compose downEnvironment Variables
Root .env
| Variable | Description | Default |
|----------|-------------|---------|
| KEYCLOAK_URL | Keycloak base URL | http://localhost:8081 |
| SSO_ISSUER_URI | OIDC issuer for JWT validation | http://localhost:8081/realms/wissen |
| MONGO_URI | MongoDB connection string | mongodb+srv://... |
| PORT | Backend server port | 8090 |
| PORTAL_PORT | Frontend portal port | 3000 |
frontend/.env
| Variable | Description | Default |
|----------|-------------|---------|
| VITE_API_URL | Backend API URL | http://localhost:8090 |
| VITE_SSO_AUTHORITY | OIDC authority URL | http://localhost:8081/realms/wissen |
| VITE_SSO_CLIENT_ID | Keycloak client ID | developer-portal |
| VITE_KEYCLOAK_URL | Keycloak server URL | http://localhost:8081 |
| VITE_DEV_PORT | Vite dev server port | 3000 |
Port Conflict Resolution
If ports are already in use:
Check what's using the port:
netstat -ano | findstr :PORTStop Docker containers if running locally:
docker stop wissen-frontend wissen-backendOr change the port in the relevant
.envfile andvite.config.ts.
API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /actuator/health | Health check |
| GET | /api/v1/me | Current user info |
| GET | /api/v1/applications | List applications |
| POST | /api/v1/applications | Register new application |
| GET | /api/v1/applications/:id | Get application detail |
| GET | /api/v1/applications/:id/sdk-config | Get SDK config |
| DELETE | /api/v1/applications/:id | Delete application |
| GET | /api/v1/approvals/pending | Pending approvals |
| POST | /api/v1/approvals/:workflowId/decision | Approve/reject |
| GET | /api/v1/audit | Audit logs |
Testing
cd backend
npm testSwitching to Microsoft Entra ID
Change 2 environment variables:
# .env
SSO_ISSUER_URI=https://login.microsoftonline.com/{tenant-id}/v2.0
# frontend/.env
VITE_SSO_AUTHORITY=https://login.microsoftonline.com/{tenant-id}/v2.0Everything else — JWT validation, role extraction, SDK integration — works identically.
SDK Usage
const { WissenSsoMiddleware } = require('@wissen/sso-sdk');
const app = express();
const sso = new WissenSsoMiddleware({
issuerUri: 'http://localhost:8081/realms/wissen',
clientId: 'your-client-id',
});
// Protect an entire route group
app.use('/api', sso.protect());
// Protect specific routes with role check
app.get('/admin', sso.requireRole('admin'), handler);
// Get authenticated user info
app.get('/me', sso.authenticate(), (req, res) => {
res.json(req.user);
});