Autentificare
GLog este un OAuth2 Resource Server: fiecare apel /api/v1/app|admin/** cere un
JWT valid din care se derivă autoritățile audit:read|write|admin și claim-ul
tenant (izolare multi-tenant — scrierea cu tenantId ≠ tenant din token → 403).
Convertorul GlogJwtAuthConverter acceptă două proveniențe, unificate, ca să meargă
identic pentru oameni și pentru servicii:
- Scope-uri (
scope/scp) →SCOPE_*. Clienții de tip serviciu (ex.glog-ingestfolosit de GNotify) poartăaudit:writepe această cale. - Roluri de realm (
realm_access.roles) → mapate peaudit:*:ROLE_ADMIN(sauadmin) →audit:read + audit:write + audit:adminROLE_USER(sauuser) →audit:read- prefixul
ROLE_și majuscularea sunt normalizate.
Cele trei moduri (profil Spring)
Section titled “Cele trei moduri (profil Spring)”Modurile sunt exclusive per deployment, selectate prin profil:
| Profil | Autentificare | Identități | Când |
|---|---|---|---|
localdev | ocolită (principal sintetic, tenant demo) | — | dezvoltare locală, fără token |
localauth | de sine stătătoare — user/parolă, token HS512 auto-emis | tabela locală app_user | deployment real fără Keycloak |
staging | Keycloak resource server (RS256, realm interdictii) | realm interdictii | integrare SSO cu restul gStack |
dualauth | ambele — Keycloak și user/parolă simultan | realm + app_user | un deployment cu ambele căi de login |
Deployment demo curent:
glog.gstack.esempla.systemsrulează pe profiluldualauth(Keycloak și user/parolă) cu AMQP activ (RabbitMQ) — după resize-ul box-ului la 8GB. Admin implicit:admin/qweASD123.
Mod localauth — user/parolă (fără Keycloak)
Section titled “Mod localauth — user/parolă (fără Keycloak)”Permite GLog să ruleze ca implementare reală fără IdP extern. Expune trei endpoint-uri
publice sub /api/auth:
| Metodă | Cale | Descriere |
|---|---|---|
| POST | /api/auth/register | auto-înregistrare → USER read-only; 201 + token; 409 dacă există; 400 la validare |
| POST | /api/auth/login | schimbă credențialele pe un token; 401 la credențiale greșite / cont dezactivat |
| GET | /api/auth/me | (Bearer) → {username, tenant, authorities} |
Token-ul este un JWT HS512 auto-emis (semnat cu GLOG_AUTH_JWT_SECRET), modelat exact
ca un token Keycloak (realm_access.roles + tenant) — de aceea același
GlogJwtAuthConverter și aceleași reguli de autorizare se aplică nemodificat.
Admin de bootstrap (GLOG_ADMIN_USER/GLOG_ADMIN_PASSWORD, implicit admin/admin)
este creat la prima pornire, ca să existe mereu o cale de intrare — schimbați parola în
orice deployment real.
Corpul răspunsului la login/register:
{ "accessToken": "eyJhbGciOiJIUzUxMiJ9…", "tokenType": "Bearer", "expiresAt": 1753617600, "username": "admin", "role": "ADMIN", "tenant": "demo" }Configurare (application-localauth.yml, override prin env)
Section titled “Configurare (application-localauth.yml, override prin env)”| Variabilă | Implicit | Rol |
|---|---|---|
GLOG_AUTH_JWT_SECRET | — (dev fallback) | secret HS512, ≥ 64 caractere. Obligatoriu în prod. |
GLOG_AUTH_TOKEN_TTL | 28800 (8h) | durata token-ului (secunde) |
GLOG_AUTH_TENANT | demo | tenant pentru utilizatorii înregistrați + admin bootstrap |
GLOG_ADMIN_USER / GLOG_ADMIN_PASSWORD | admin / admin | admin de bootstrap (doar când app_user e goală) |
Rulare: SPRING_PROFILES_ACTIVE=localauth,no-amqp.
Mod staging — Keycloak (realm interdictii)
Section titled “Mod staging — Keycloak (realm interdictii)”- UI web → client public
glog-web(PKCE S256, doar browser). - Servicii M2M (ex. GNotify) → client confidențial + grant
client_credentials(ex.glog-ingest, scopeaudit:write). - Regulă: browser → client public + PKCE; serviciu → client confidențial.
KEYCLOAK_ISSUER_URI=https://sso.gstack.esempla.systems/realms/interdictii.- Rulare:
SPRING_PROFILES_ACTIVE=staging,no-amqp.
Mod dualauth — Keycloak ȘI user/parolă simultan
Section titled “Mod dualauth — Keycloak ȘI user/parolă simultan”Un singur resource server acceptă două proveniențe de token, rutate după claim-ul
iss de un JwtIssuerAuthenticationManagerResolver:
- Keycloak (realm
interdictii, RS256) — validat față de JWKS-ul realm-ului (KEYCLOAK_ISSUER_URI). - local (HS512) — token-uri emise de
/api/auth/login, validate cuGLOG_AUTH_JWT_SECRET;iss = glog-localauth.
Ambele trec prin același GlogJwtAuthConverter, deci autorizarea (audit:* + tenant)
e identică indiferent de calea de login. Ecranul de login afișează butonul Keycloak
ȘI formularul user/parolă. Rulare: SPRING_PROFILES_ACTIVE=dualauth (necesită
Postgres + RabbitMQ + issuer Keycloak accesibil); slim: dualauth,no-amqp.
Rulare completă (AMQP)
Section titled “Rulare completă (AMQP)”Profilurile localauth/dualauth pornesc stiva completă (DB + RabbitMQ) când sunt
rulate fără no-amqp (spring.autoconfigure.exclude: [] re-activează AMQP). Broker
dedicat glog-rabbitmq; ingest AMQP: publish pe exchange-ul audit.events (routing
key = codul serviciului) → consumatorul stochează evenimentul. Slim (fără broker):
adăugați profilul no-amqp.
Frontend
Section titled “Frontend”environment.authMode ∈ { keycloak | local | dual | demo }:
local(build--configuration=localauth) → ecran de login user/parolă + înregistrare; token-ul e păstrat înlocalStorageși atașat caBearer.dual(build--configuration=dual) → ambele: buton Keycloak + formular user/parolă.keycloak→ fluxul OIDC/PKCE.demo→ intrare demo (auth ocolită).
Butonul de Deconectare este ancorat în bara laterală stângă (sub blocul de utilizator):
Keycloak → redirect logout la IdP; local/demo → curăță sesiunea → /login.
Legături
Section titled “Legături”- 🔌 API — endpoint-uri funcționale + operaționale
- Colecție Postman:
docs/glog.postman_collection.json(folderul Auth are cererilelocalauth+client-credentials) - Referință integrator:
docs/api.md
La zi: 2026-07-27 · surse de cod: config/{SecurityConfig,LocalAuthSecurityConfig,GlogJwtAuthConverter}, web/AuthResource, security/local/*.