Skip to content

Sessiohallinta ja kirjautumismekanismit

Joonas Javanainen edited this page Oct 14, 2024 · 6 revisions

Sessiohallinta

eVaka käyttää perinteisiä tilallisia sessioita api-gatewayssa, jossa session sisältö tallennetaan Redis-tietokantaan ja session ID tallennetaan selainkeksiin (secure+httpOnly). Sessioilla on oletuksena lyhyt pituus (32 min), mutta API-kutsut järjestelmään nollaavat pituuslaskurin ja aktiivisesti järjestelmää käyttävä käyttäjä ei lennä ulos. Sessioiden vanhentuminen on toteutettu kahdella päällekkäisellä mekanismilla: keksin Expires/Max-Age -arvolla, ja Rediksen sessiotiedon EX-arvolla.

Työntekijöiden mobiililaitteiden puolella tavallisen session lisäksi on ns. long term token -tunniste, jota käytetään automaattisesti session luontiin jos sellaista ei tällä hetkellä ole. Tämä tunniste tallentuu eVakan tietokantaan laitteen parituksen yhteydessä, ja sen avulla laitetta ei tarvitse parittaa uudelleen niin kauan kuin laitteen oma selain säilyttää keksin johon se on tallennettu. Jos eVakaa ei käytetä laitteella pitkään aikaan, käyttöjärjestelmästä riippuen keksi saattaa tyhjentyä ja silloin uusi paritus täytyy tehdä.

eVakassa on myös muutama järjestelmäintegraatioon tarkoitettu REST-endpoint, joissa käytetään tavallista HTTP Basic-tunnistautumista. Nämä on rajattu omaan lokeroonsa API-polkujen avulla, eikä Basic-tunnistautumisen kautta voi kutsua muita kuin tiettyjä integraatioendpointteja tai tavallisen tunnistautumisen kautta kutsua niitä. Integraatioendpointit ovat tilattomia, eikä niitä varten ole erillistä sessiohallintaa.

eVaka käyttää mm. näitä avoimen lähdekoodin kirjastoja sessiohallintaan:

  • express-session: yleinen sessiomekanismi
  • connect-redis: Redis-tallenusmekanismi sessioille

Kirjautumismekanismit

eVaka käyttää kirjautumiseen ydinjärjestelmän ulkopuolisia palveluita SAML-integraatioiden kautta. Koko eVaka voidaan jakaa kahteen osaan ja molemmissa osissa on kaksi SAML-integraatiota:

Kuntalaisen puoli (koodin puolella ns. "citizen", "enduser", tai "customer"):

  • Suomi.fi SAML vahva tunnistautuminen
  • Keycloak SAML ("citizen"/"customer" realm)

Työntekijöiden puoli (koodin puolella ns. "internal" tai "employee"):

  • AD SAML
  • Keycloak SAML ("employee"/"evaka" realm)

Näiden lisäksi internal-puolella on mobiililaitteille oma paritusmekanismi, jolla perustetaan pitkäkestoinen token laitteen automaattikirjautumiselle. Mobiililaitteet ovat API-poluissa omassa lokerossaan, eikä niillä ole pääsyä tavallisten käyttäjien endpointteihin tai toisinpäin.

eVaka käyttää mm. näitä avoimen lähdekoodin kirjastoja SAML-kirjautumiseen:

  • passport: yleinen viitekehys kirjautumiselle
  • passport-saml: SAML-viestien luku ja kirjoitus, integraatio passportin kanssa
  • zod: SAML-kirjautumisviestien käyttäjätietojen tarkempi luku ja validaatio. passport-saml lukee käyttäjä-"profiilin" kentät XML:stä tavalliseen JS-objektiin, joka sitten syötetään tälle kirjastolle

Jokaiselle SAML-integraatiolle luodaan oma passport-saml konfiguraatio-objekti, joka sisältää enimmäkseen kaikille integraatioille yhteisiä kenttiä, mutta myös integraatiokohtaisia kenttiä (esim. IDP:n osoite, sertifikaatit, joskus tarkempia SAML-protokollan konfiguraatioita) joista iso osa luetaan ympäristömuuttujista.

Suomi.fi SAML

eVaka tukee vahvaa Suomi.fi-kirjautumista kuntalaisen puolella, ja tunnistaa käyttäjät henkilötunnuksen perusteella. Kirjautuminen ilman henkilötunnusta ei ole mahdollista, eikä eVaka tue Suomi.fi:n tunnistautumistapoja joissa henkilötunnusta ei palauteta sovellukselle.

Suomi.fi-käyttäjä syntyy eVakan tietokantaan ensimmäisen kirjautumisen yhteydessä, jos järjestelmän tekemä VTJ-haku löytää henkilötiedot Suomi.fi:n palauttamalla henkilötunnuksella. Jos henkilötietoja ei löydy tai haun aikana tapahtuu virhe, kirjautuminen keskeytyy eikä uutta käyttäjää synny.

AD SAML

eVaka tukee AD:n kautta tapahtuvaa kirjautumista työntekijöiden puolella, ja tunnistaa käyttäjät joko AD:n sisäisen pysyvän tunnisteen tai henkilönumeron perusteella. eVaka ei itse tarkista tai vaadi mitään tiettyjä AD-rooleja vaan hyväksyy minkä tahansa käyttäjän joka pääsee AD SAML -kirjautumisesta läpi. Jos kaikkia mahdollisia AD-käyttäjiä ei haluta päästää sisään järjestelmään, AD:ssa tulee olla oma roolitarkistus jolla rajataan pääsyä sovellukseen.

AD-käyttäjiä ei tavallisesti provisioida etukäteen, vaan käyttäjä syntyy eVakan tietokantaan ilman rooleja ensimmäisen kirjautumisen yhteydessä, ja pääkäyttäjä tai esimies voi sen jälkeen luvittaa sopivat roolit sovelluksen omasta käyttöliittymästä.

Keycloak citizen SAML

Kuntalaisten puolella voi olla käytössä SAML-integraatio Keycloak-järjestelmään, jonka kautta kuntalaiset voivat kirjautua "kevyesti" pelkällä käyttäjätunnuksella ja salasanalla. eVaka vaatii että Keycloak palauttaa käyttäjän henkilötunnuksen SAML-kirjautumisviestissä, koska käyttäjä tunnistetaan järjestelmän sisällä sen avulla. Keycloakin kautta kirjautuneet käyttäjäsessiot

eVaka ei tee oletuksia siitä miten Keycloak on konfiguroitu, mutta tavallisesti käyttäjät voivat rekisteröityä Keycloakin kautta Suomi.fi-tunnistautumisen avulla jolloin henkilötunnus tallentuu Keycloakin tietokantaan, ja Keycloak voi välittää sen eVakalle kirjautumisten yhteydessä.

Keycloak employee SAML

Työntekijöiden puolella voi olla käytössä SAML-integraatio Keycloak-järjestelmään, joka on tarkoitettu palveluntuottajakäyttäjille joilla ei ole AD-tunnuksia.

eVaka ei tee oletuksia siitä miten Keycloak on konfiguroitu tai miten käyttäjät luodaan sinne. Kaksivaiheinen tunnistautuminen ja/tai Suomi.fi-tunnistautuminen ovat suositeltavia, koska Keycloak-käyttäjät ovat työntekijäpuolella suoraan rinnastettavissa AD-käyttäjiin ja käyttöoikeudet riippuvat käytännössä vain luvituksista.

SAML-endpointit eVakan api-gatewayssa

eVakan api-gateway sisältää muutaman standardimuotoisen SAML-endpointin jotka löytyvät jokaiselle SAML-integraatiolle, mutta endpointtien polkujen alkuosa on jokaiselle eri. Endpointtien toteutus on 90% yhteistä koodia, mutta käyttäjätietojen lukeminen SAML-kirjautumisviestistä on erilainen eri toteutuksissa (esim. Suomi.fi SAMLissa luetaan henkilötunnus, AD-SAMLissa luetaan henkilönumero, jne...).

/prefix/login GET:

  1. passport-saml luo SAML-viestin (AuthnRequest) ja ohjaa käyttäjän selaimen IDP:n puolelle. eVakan redikseen tallentuu tieto käynnistetystä SAML-pyynnöstä, jota käytetään myöhemmin paluuendpointissa ns. InResponseTo-validaatioon

/prefix/login/callback POST (ns. SAML "POST binding"):

  1. passport-saml lukee SAML-viestin (AuthnResponse), validoi sen, ja kutsuu eVakan yleistä loginVerify-callbackia
  2. loginVerify-callback lukee käyttäjän tiedot SAML-vastauksesta ja kutsuu yksittäisen kirjautumistavan login-funktiota
  3. login-funktio tarkistaa ja/tai luo käyttäjän evaka-service:n kautta. Jos evaka-service palauttaa virheen, kirjautuminen keskeytyy
  4. kontrolli palaa passport-samlille joka kutsuu yleistä loginHandler-routen callbackia, joka ohjaa käyttäjän selaimen sovellukseen

/prefix/logout GET:

  1. passport-saml luo SAML-viestin (LogoutRequest) ja ohjaa käyttäjän selaimen IDP:n puolelle. eVakan redikseen tallentuu tieto käynnistetystä SAML-pyynnöstä, jota käytetään myöhemmin paluuendpointissa ns. InResponseTo-validaatioon

/prefix/logout/callback GET/POST (ns. SAML "redirect binding" ja "POST binding"):

  1. passport-saml lukee SAML-viestin (LogoutResponse tai LogoutRequest), validoi sen, ja kutsuu eVakan yleistä logoutVerify-callbackia
  2. Jos kyse oli IDP-lähtöisestä uloskirjautumisesta (LogoutRequest), passport-saml luo SAML-viestin ja ohjaa käyttäjän selaimen IDP:n puolelle. Jos kyse oli SP-lähtöisestä uloskirjautumisesta (LogoutResponse), passport-saml kutsuu yleistä logoutHandler-routen callbackia, joka ohjaa käyttäjän selaimen takaisin sovelluksen alkusivulle