Skip to content

Sessiohallinta ja kirjautumismekanismit

Joonas Javanainen edited this page Dec 12, 2024 · 5 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-tallennusmekanismi sessioille

Alla olevassa taulukossa on listattu eri käyttäjätyypit ja niiden sessiokeksit. Tällä hetkellä kunnan mobiililaitteet käyttävät samaa sessiokeksiä kuin työntekijät, joten yhdessä selaimessa ei voi olla samaan aikaan näissä kahdessa käyttöliittymässä kirjautuneena.

Käyttäjätyyppi Julkinen polku, jossa sovellus on Sessiokeksi Julkinen polku, jossa API:t ovat
Kuntalaiset / evaka.eugw.session /api/application/
Työntekijät /employee/ evaka.employee.session /api/internal/
Kunnan mobiililaitteet /employee/mobile/ evaka.employee.session /api/internal/

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:

  • node-saml: SAML-viestien luku ja kirjoitus
  • zod: SAML-kirjautumisviestien käyttäjätietojen tarkempi luku ja validaatio. node-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 node-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 merkitään kevytkirjautuneiksi (CitizenAuthLevel.WEAK), ja pääsevät käsiksi vain osaan järjestelmän toimintoja.

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. node-saml luo SAML-viestin (AuthnRequest) ja käyttäjän selain ohjataan 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. node-saml lukee SAML-viestin (AuthnResponse), validoi sen, ja palauttaa SAML "profilen", joka pitää sisällään SAML-viestin assertiosta luetut käyttäjätiedot
  2. yksittäisen kirjautumistavan authenticate-funktio lukee SAML profilesta halutut kentät, sekä validoi ja/tai luo käyttäjän kutsumalla evaka-serviceä
  3. käyttäjän selain ohjataan sovellukseen joko virhesivulle tai alunperin pyydetylle sivulle, riippuen kirjautumisen onnistumisesta

/prefix/logout GET:

  1. node-saml luo SAML-viestin (LogoutRequest) ja käyttäjän selain ohjataan 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. node-saml lukee SAML-viestin (LogoutResponse tai LogoutRequest), validoi sen, ja palauttaa IDP-lähtöisessä uloskirjautumisessa (LogoutRequest) SAML "profilen", joka pitää sisällään SAML-viestistä luetut SAML-session tunnistetiedot
  2. Jos kyse oli IDP-lähtöisestä uloskirjautumisesta (LogoutRequest), session tunnistetietojen perusteella poistetaan rediksestä käyttäjän sessio, ja käyttäjän selain ohjataan takaisin IDP:n puolelle. Jos kyse oli SP-lähtöisestä uloskirjautumisesta (LogoutResponse), käyttäjäsessio poistetaan, ja käyttäjän selain ohjataan takaisin sovelluksen alkusivulle

Kehityskäyttöön tarkoitetut "mock"-kirjautumismekanismit

Paikallisessa kehitysympäristössä ja automaattitesteissä on käytössä "mock"-kirjautumismekanismit oikeiden Suomi.fi- ja AD-kirjautumismekanismien sijaan. Mock-toteutukset eivät toimi SAML-tekniikalla, vaan toteutus on yksinkertaisin mahdollinen toteutus jossa voi valita käyttäjän, ja josta syntyy oikeankaltainen käyttäjäsessio.

Suomi.fi mock listaa valittavaksi kehitysympäristön mock VTJ:ssä olevat kuntalaiset. Jos valitaan käyttäjä joka löytyy mock VTJ:stä mutta ei tietokannasta, tilanne vastaa uuden Suomi.fi-käyttäjän ensimmäistä kirjautumista. Jos valitaan jo tietokannassa oleva käyttäjä, tilanne vastaa jo tunnetun käyttäjän kirjautumista.

AD mock listaa valittavaksi tietokannasta löytyvät työntekijät ja mahdollistaa myös täysin uuden käyttäjän luonnin, jolla voidaan simuloida uuden AD-käyttäjän ensimmäistä kirjautumista. Jos valitaan jo tietokannassa oleva käyttäjä, tilanne vastaa jo tunnetun käyttäjän kirjautumista.