Tokenit ja claimit
Kaikki tokenit allekirjoitetaan ES256:lla (ECDSA + P-256 + SHA-256).
Julkiset avaimet ovat aina saatavilla /.well-known/jwks.json-osoitteessa;
tokenin headerin kid kertoo, mitä avainta käytettiin. Katso
Avaimet ja allekirjoitus sille,
miten avainten kierto ja välimuistitus toimivat resurssipalvelimen
näkökulmasta.
Access token
Osio nimeltä “Access token”Access token on ES256-allekirjoitettu JWT, jonka headerissä on
typ: at+jwt (RFC 9068) — tämä erottaa sen ID tokenista niin, ettei
resurssipalvelin voi vahingossa hyväksyä väärän tyyppistä tokenia.
Oletuselinaika on 3600 sekuntia (1 tunti); elinaika on client-kohtainen asetus, ei tenantin globaali asetus.
| Claim | Tyyppi | Selitys |
|---|---|---|
iss |
string | Issuer — tenantin JWT-issuer-URL |
sub |
string | Käyttäjän UUID (tai client_credentials-grantissa clientin client_id) |
aud |
string | Sama kuin iss |
iat |
number | Myöntöaika (Unix-sekunteina) |
exp |
number | Vanhenemisaika |
scope |
string | Myönnetyt scopet välilyönnillä eroteltuna |
client_id |
string | Tokenin pyytänyt OAuth-client |
{ "iss": "https://id.esimerkki.fi", "sub": "01923f7a-beef-7f5a-b1cd-000000000001", "aud": "https://id.esimerkki.fi", "iat": 1714348800, "exp": 1714352400, "scope": "openid profile email", "client_id": "esimerkki-web"}ID token
Osio nimeltä “ID token”Oletuselinaika on 3600 sekuntia; myös tämä on client-kohtainen.
Scope-sarakkeessa merkityt claimit puuttuvat tokenista kokonaan, jos
vastaavaa scopea ei pyydetty — eivät esiinny tyhjänä tai null-arvoina.
| Claim | Tyyppi | Vaadittu scope | Selitys |
|---|---|---|---|
iss |
string | openid |
Issuer |
sub |
string | openid |
Käyttäjän UUID |
aud |
string | openid |
Pyytäneen clientin client_id |
iat |
number | openid |
Myöntöaika |
exp |
number | openid |
Vanhenemisaika |
auth_time |
number | openid |
Milloin käyttäjä oikeasti todennettiin. SSO-tilanteessa tämä on hetki, jolloin uudelleenkäytetty istunto luotiin — ei hetki, jolloin tämä koodi myönnettiin. Yhdistä max_age-parametriin pakottaaksesi tuoreen kirjautumisen. |
nonce |
string | openid |
Palautuu sellaisenaan, jos annettiin authorize-pyynnössä |
sid |
string | openid |
Sessiotunniste — backchannel-uloskirjautumisen korrelointiin |
amr |
string[] | openid |
Todennustapa (RFC 8176), ks. taulukko alla |
at_hash |
string | openid |
Access tokenin tiiviste (OIDC Core §3.1.3.6): SHA-256:n vasemman puoliskon base64url. Sitoo ID tokenin samalla vastauksella myönnettyyn access tokeniin. |
email |
string | email |
Sähköpostiosoite |
email_verified |
boolean | email |
Ks. huomio alla |
name |
string | profile |
Näyttönimi (puuttuu jos ei asetettu) |
phone_number |
string | phone |
E.164-muotoinen puhelinnumero |
phone_number_verified |
boolean | phone |
true kun puhelin on OTP-vahvistettu |
roles |
string[] | roles |
Tenantin määrittelemät globaalit roolit, esim. ["billing_admin"] |
orgs |
array | orgs |
Organisaatiojäsenyydet — ks. Organisaatiot |
groups |
string[] | groups |
Litteät ryhmämerkkijonot, esim. ["org:{uuid}:admin"] |
amr-arvot todennustavoittain
Osio nimeltä “amr-arvot todennustavoittain”| Kirjautumistapa | amr |
|---|---|
| Magic link (sähköposti tai SMS) | ["otp"] |
| Magic link + TOTP-lisävarmennus | ["otp", "mfa"] |
| Passkey käyttäjän varmennuksella (PIN/biometriikka) | ["hwk", "user", "mfa"] |
| Google (tai muu ulkoinen OIDC-broker) | Tyhjä (amr puuttuu kokonaan) — ulkoisen tarjoajan todennustapaa ei voida attestoida, joten claimia ei väitetä |
Käytä amr-claimia porttina herkille toiminnoille, esim. vaadi "mfa" sen
sisällä ennen kuin sallit maksuasetusten muutoksen.
acr-claimia (Authentication Context Class Reference) ei ole vielä
toteutettu millekään kirjautumistavalle — sitä ei löydy claims_supported-
listasta eikä myönnetyistä tokeneista.
Roolit ja organisaatiot ID tokenissa
Osio nimeltä “Roolit ja organisaatiot ID tokenissa”"roles": ["billing_admin", "developer"]Org-scopatut roolit näkyvät kunkin org-tietueen sisällä (vaatii sekä
roles- että orgs-scopen):
"orgs": [ { "id": "5e3b1a2c-0000-0000-0000-000000000001", "name": "Esimerkki Oy", "role": "admin", "roles": ["project_manager"], "groups": ["laskuttajat"] }]roles- ja groups-kentät org-tietueen sisällä puuttuvat kokonaan (eivät
ole tyhjä lista) kun käyttäjällä ei ole niitä. Täysi selitys org- ja
group-claimeista: Organisaatiot.
Esimerkki (dekoodattu, kaikki scopet)
Osio nimeltä “Esimerkki (dekoodattu, kaikki scopet)”{ "iss": "https://id.esimerkki.fi", "sub": "01923f7a-beef-7f5a-b1cd-000000000001", "aud": "esimerkki-web", "iat": 1714348800, "exp": 1714352400, "auth_time": 1714348795, "nonce": "randomnonce", "sid": "01923f7a-beef-7f5a-b1cd-000000000099", "amr": ["otp"], "email": "kayttaja@esimerkki.fi", "email_verified": true, "name": "Matti Meikäläinen", "phone_number": "+358401234567", "phone_number_verified": true, "roles": ["global_admin"], "orgs": [ { "id": "5e3b1a2c-0000-0000-0000-000000000001", "name": "Esimerkki Oy", "role": "admin", "roles": ["billing_admin"], "groups": ["laskuttajat"] } ], "groups": ["org:5e3b1a2c-0000-0000-0000-000000000001:admin"]}Refresh token
Osio nimeltä “Refresh token”Oletuselinaika on 86400 sekuntia (24 tuntia), client-kohtaisesti säädettävä.
Refresh token on opaakki merkkijono — se tallennetaan SHA-256-tiivisteenä, eikä sitä voi dekoodata kuten JWT:tä.
Se rotatoituu joka käytöllä: uusi refresh token korvaa käytetyn. Kumotun (jo käytetyn) tokenin uudelleenkäyttöyritys tulkitaan varkaudeksi ja kumoaa koko token-perheen — kaikki kyseisen käyttäjä+client-parin sessiot.
Refresh token myönnetään vain, kun offline_access-scope pyydettiin ja
clientille on sallittu refresh_token-grant.
Miten resurssipalvelin validoi access tokenin
Osio nimeltä “Miten resurssipalvelin validoi access tokenin”- Hae signing key
/.well-known/jwks.json-osoitteesta tokeninkid:n perusteella. - Varmista allekirjoitus (ES256).
- Varmista
expei ole umpeutunut. - Varmista
aud/isstäsmäävät odotettuun tenanttiin. - Varmista headerin
typonat+jwt(erottaa access tokenin ID tokenista).
Vaihtoehtoisesti käytä introspektiota (RFC 7662), jos et halua validoida JWT:tä itse — palauttaa myös tiedon, onko token vielä voimassa vai peruutettu:
curl -s -u "esimerkki-web:secret" \ -d "token=<access_token>" \ https://id.esimerkki.fi/introspectVaatii clientin todennuksen (Basic-auth client_id:client_secret).