Verzia Spring security, na ktorej NAE dependuje, poskytuje oauth2 autorizáciu prostredníctvom JWT tokenov. Default-nú security konfiguráciu s týmto nastavením (SecurityConfigurationSSO
, OAuthUserServiceConfiguration
) je možné aktivovať úpravou application.properties:
nae.oauth.enabled=true |
Do properties je následne potrebné špecifikovať cesty na preddefinované endpoint-y autorizačného serveru. Príklad pre Keycloak IDM (ktorý beží pod localhost:8080):
security.oauth2.resource.jwk.key-set-uri=http://localhost:8080/auth/realms/Test/protocol/openid-connect/certs security.oauth2.resource.user-info-uri=http://localhost:8080/auth/realms/Test/protocol/openid-connect/userinfo |
Keď client (napr. frontend) vyžiada akýkoľvek resource z backend-u, autorizuje sa prostredníctvom access_token-u, ktorý obdržal z autorizačného serveru. Tento token do authorization header-u vkladá ako Bearer token. Backend (Spring security) používateľa overí a dotiahne jeho údaje z autorizačného serveru. Backend následne použitím implementácie triedy IOauthUserMapper
z údajov vyskladá používateľa (Authentication → LoggedUser).
Defaultne existujú dve implementácie IOauthUserMapper
; OAuthUserMapper
pre remote user base a ServiceUserMapper
pre vlastný user base.
OAuthUserMapper
je inicializovaný v prípade, že nasledovná property je aktivovaná. Interne používa implementáciu rozhrania IOAuthUserService
na dohľadanie/vytvorenie nového používateľa (OAuthUser
).
nae.oauth.remote-user-base=true |
Táto implementácia mapper-u požaduje v properties špecifikovať kľúče mapovaných údajov:
nae.oauth.mapper.name=given_name nae.oauth.mapper.surname=family_name nae.oauth.mapper.email=email nae.oauth.mapper.id=sub |
Spolu s ním je inicializovaná aj service OAuthUserService
, ktorá je závislá na IRemoteUserResourceService
a IRemoteGroupResourceService
. Implementácie týchto dvoch rozhraní je potrebné poskytnúť buď vlastné, alebo použiť defaultné, ktoré sú špecifické pre Keycloak.
Ak je autorizačný server Keycloak, stačí pridať nasledovné properties:
nae.oauth.keycloak=true security.oauth2.client.realm=Test security.oauth2.client.serverUrl=http://localhost:8080/auth |
V tomto prípade sú použité implementácie KeycloakUserResourceService
a KeycloakGroupResourceService
, ktoré cez Keycloak Admin API pristupujú k používateľom. Autorizácia backend-u voči Keycloak-u na doťahovanie informácií o používateľoch pre potreby NAE je defaultne realizovaná cez clientId a clientSecret (KeycloakConfiguration
).
security.oauth2.client.clientId=test-client security.oauth2.client.clientSecret=abcedfgh-abcd-1234-4567-12345555d338 |
Implementácia OAuthUserService
s používateľmi narába bez potreby mať ich od začiatku naimportovaných v databáze. Používatelia sú cez IRemoteUserResourceService
dynamicky doťahovaní poďla potreby. Pri prvom prihlásení (OAuthUserMapper
) alebo keď je používateľovi v NAE prvýkrát pridelená autorita alebo procesná rola, je o ňom vytvorený minimálny záznam v MongoDB, ktorý obsahuje autority, procesné roly, skupiny, lokálne ID a ID v originálnej user base. OAuthUser
a OAuthLoggedUser
objekty sa interne reprezentujú (cez stringId) svojim ID v originálnej user base.
Metódy OAuthUserService
, ktorých návratová hodnota je typu zoznam/stránka používateľov, vracajú používateľov namapovaných na záznamy v DB (teda s autoritami, procesnými rolami …) a taktiež používateľov, ktorí sa v DB ešte nenachádzajú (bez autorít, rolí, taktiež nemajú internú property _id).
Upravovanie údajov používateľov nájdených prostredníctvom ID a ich následné uloženie cez save metódu IUserService
je vhodné, pokiaľ používateľ bol dohľadaný cez metódu resolveById
. Táto metóda v OAuthUserService
používateľa vytvorí v DB, ak dosiaľ neexistuje, a pridelí mu default autoritu, skupinu, atp. Metóda findById
v tejto service používateľa môže vrátiť aj keď sa ten v MongoDB stále nenachádza a teda nebude mať default nastavené údaje.
Záznamy o anonymných používateľoch a systémovom používateľovi sú naďalej ukladané v MongoDB.
"auth": { "address": "http://localhost:8080/api/", "authentication": "SSO", "sso": { "refreshUrl": "https://idm.netgrif.com:8443/auth/realms/TEST/protocol/openid-connect/token", "login": "https://idm.netgrif.com:8443/auth/realms/TEST/protocol/openid-connect/auth", "logout": "https://idm.netgrif.com:8443/auth/realms/TEST/protocol/openid-connect/logout", "automaticLogin": true, "refreshConfig": { "clientID": "frontend", "clientSecret": "TOKEN" } }, "endpoints": { "login": "auth/login", "logout": "auth/logout", "signup": "auth/signup", "verification": "auth/verify", "verify": "auth/token/verify", "invite": "auth/invite", "reset": "auth/reset", "recover": "/auth/recover" }, "sessionBearer": "Authorization", "jwtBearer": "X-Jwt-Token" }, |