Backend

Konfigurácia

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 KeycloakUserResourceServicea 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

User management

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.

Frontend

"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"
},