Europe Login is a stateless JWT-based identity provider for Dutch companies. It mirrors the e-Herkenning assurance-level model but runs entirely on GloryLabs infrastructure.
┌─────────────────┐ HTTPS ┌─────────────────────────────────────┐
│ Angular 20 SPA │ ◄────────────► │ Spring Boot 3 (port 8091) │
│ port 4301 │ │ /api/auth /api/onboarding │
└─────────────────┘ │ /api/companies /api/audit │
└──────────┬──────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
┌──────▼──────┐ ┌───────▼──────┐ ┌───────▼──────┐
│ PostgreSQL │ │ Redis │ │ GoCardless │
│ port 5434 │ │ port 6380 │ │ PSD2 API │
└─────────────┘ └──────────────┘ └──────────────┘
| Level | Meaning | How achieved |
|-------|---------|--------------|
| BASIS | KvK verified | KvK format check + KvK API |
| MIDDEN | Bank account owner matches KvK name | BASIS + PSD2 name match |
| HOOG | Full identity review | MIDDEN + manual document review (future) |
BESTUURDER / GEMACHTIGDE / GEVOLMACHTIGDE), linked to Companynl.glorylabs.europelogin
├── annotation/ @Auditable AOP annotation
├── aspect/ AuditAspect — intercepts @Auditable methods
├── config/ SecurityConfig, RedisConfig, OpenAPI config
├── controller/ AuthController, CompanyController,
│ OnboardingController, AuditController
├── dto/ Request/response records (API boundary)
├── entity/ JPA entities + enums
├── exception/ Domain exceptions + GlobalExceptionHandler
├── repository/ Spring Data JPA repositories
├── security/ JwtAuthenticationFilter, JwtTokenProvider,
│ RepresentativeUserDetails, RepresentativeUserDetailsService
└── service/ CompanyAuthService, TokenService, OnboardingService,
AuditService, KvkValidationService,
BsnEncryptionService, Psd2Service
POST /api/auth/login
1. validateFormat(kvkNumber) ← KvkValidationService
2. findByKvkNumberAndActiveTrue() ← CompanyRepository
3. meetsAssuranceLevel(actual, req) ← ordinal comparison
4. findByEmailAndActiveTrue(email) ← AuthorizedRepresentativeRepository
5. rep.company.id == company.id ← ownership check
6. passwordEncoder.matches(pw, hash) ← BCrypt
7. tokenService.issueToken(...) ← JWT + LoginSession + Redis
8. auditService.record(LOGIN_SUCCESS) ← hash-chained audit event
POST /api/onboarding → step 1: validate KvK, create OnboardingSession
POST /{id}/psd2/initiate → step 2a: GoCardless requisition
GET /{id}/psd2/complete?ref= → step 2b: fetch accounts, name match
POST /{id}/representative → step 3: capture BSN (encrypted), role
POST /{id}/complete → step 4: create Company + AuthorizedRepresentative
Assurance levels awarded:
BASISMIDDENEvery @Auditable method is intercepted by AuditAspect. For auth events, CompanyAuthService and TokenService call auditService.record() directly to include full actor info (email, KvK, role).
Each AuditEvent stores:
previousEventHash — hash of the preceding eventeventHash — SHA-256 of timestamp|eventType|actorEmail|action|result|targetEntityId|previousEventHashChain verified via GET /api/audit/verify (BESTUURDER only).
BSN is never stored in audit events (AVG/GDPR compliance).
BsnEncryptionService)@PreAuthorize("hasRole('BESTUURDER')") on audit endpointsauthenticationEntryPointAccessDeniedException mapped to 403 in GlobalExceptionHandlerAngular 20 standalone components, no NgModules. Reactive forms with signals for state.
Key components:
LoginComponent — login form (KvK + email + password + assurance level)OnboardingComponent — 5-step wizard shell (KvK → bank → representative → review → complete)DashboardComponent — post-login landingAuthService — JWT/session storage in sessionStorage, signal-based auth stateAuthGuard — CanActivateFn redirecting unauthenticated users to /loginAuthInterceptor — injects Authorization: Bearer <token> on all API calls| Service | Port | |---------|------| | Backend API | 8091 | | Frontend | 4301 | | PostgreSQL | 5434 | | Redis | 6380 |
| Branch | Namespace |
|--------|-----------|
| main | europe-login |
| develop | europe-login-staging |
push to feature/* → CI tests only
PR → develop → CI: test + build + push ghcr.io → Helm upgrade staging
PR → main → CI: test + build + push ghcr.io → Helm upgrade production
Workflows in .github/workflows/:
ci-backend.yml — Maven test + Docker build + pushci-frontend.yml — npm test + ng lint + Selenium E2E + Docker build + pushe2e.yml — full-stack E2E with postgres + redis + selenium servicesdeploy-backend.yml / deploy-frontend.yml — Helm upgrade
Reacties