Token exchange
Token Exchange i HelseID baserer seg på IETF-spesifikasjonen RFC 8693: OAuth 2.0 Token Exchange, som beskriver en protokoll for å hente ut tokens fra en STS for «impersonation» og «delegation».
I HelseID brukes denne spesifikasjonen når bakenforliggende tjenester, i hovedsak REST API-er, skal kalle andre tjenester på vegne av en autentisert person og/eller virksomhet.
Sentrale begreper
Token Exchange innfører noen nye begreper:
subject_token
: Et Access-token utstedt av HelseID som kan inneholde claims om en autentisert person og klientens virksomhet.
subject client
: En klient som har mottatt et subject_token
fra HelseID.
actor client
: En klient som ønsker å veksle inn et subject_token
ved bruk av token exchange. Hensikten med dette er å få tilbake et nytt Access-token som kan brukes til å kalle en annen tjeneste. Actor client
vil typisk være et API som vil hente data fra et annet API som også er sikret med HelseID.
Token exchange-flyten
Bruken av Token exchange i HelseID skjer med en flyt der en subject client
først ber om et Access-token fra HelseID, og deretter bruker dette tokenet mot et API som har en actor client
innebygd. Det er actor client
som gjør selve Token-exchange-kallet, men flyten gjennom hele kjeden kan være litt mer kompleks.
Overordnet flyt
- Subject client forespør autentisering av bruker og ber om tilgang til API 1
- HelseID utsteder Access-token (AT#1,
subject_token
) med tilgang til API 1 - Subject client gjør et kall til API 1, med AT#1 i Authorization-headeren
- API 1 trenger data fra API 2 og trenger dermed et Access-token for dette
- Actor client (API 1) gjør en Token Exchange-forespørsel mot Token-endepunktet på HelseID og ber om tilgang til API 2
- AT#1 er
subject_token
i denne forespørselen
- AT#1 er
- HelseId utsteder et nytt Access-token (AT#2) og returnerer det til Actor client (API 1)
- Actor client (API 1) gjør et kall til API 2 med AT#2 i Authorization-headeren
Forespørsel til HelseID med kall til Token-endepunktet
For å få utstedt et Access-token med Token exchange-mekanismen, må Actor client bruke Token-endepunktet på samme vis som en vanlig HelseID-klient. Dog må enkelte spesialparametre brukes i kallet:
grant_type
: skal alltid væreurn:ietf:params:oauth:grant-type:token-exchange
subject_token
: Access-tokenet som ble utstedt av HelseID og som skal utvekslessubject_token_type
: skal alltid væreurn:ietf:params:oauth:token-type:access_token
Et eksempel på en slik POST-forespørsel:
POST /connection/token
grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
scope=api1 api2&
subject_token=eyJhbGciOiJSUzI...lZ22kWJV4pHr8t&
subject_token_type=urn:ietf:params:oauth:token-type:access_token&
client_assertion=eyJhbGciOiJSUzI...lZ22kWJV4pHr8t&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_id=3c349ff9-20ea-4026-bf8f-f2fb9ed1bb59&
Respons ved suksess
Hvis HelseID sender ut et Access-token, så er responsen lik den som er spesifsert i RFC8693 (Token Exchange).
Feilmeldinger fra Token-endepunktet
Når det oppstår en feil i kallet til Token-endepunktet, vil HelseID sende ut en feilmelding, med en mer detaljert beskrivelse. Tabellen under beskriver de vanligste feilmeldingene du kan få:
Feilmelding | Feilbeskrivelse | Tolkning av feil |
---|---|---|
invalid_request |
invalid subject_token - [detaljert informasjon] |
Denne feilen kan for eksempel komme av at subject -tokenet ikke er utstedt av HelseID, eller at levetiden på tokenet har har gått ut. |
invalid_request |
not permitted |
Denne feilen oppstår hvis subject client ikke er konfigurert til å kunne bruke token exchange for actor client . |
invalid_target |
invalid scopes requested |
Dette oppstår dersom actor client spør om scopes som går på tvers av API-ressurser. |
invalid_request |
subject_token exchanged too many times (5) |
Dette oppstår dersom actor client forsøker å veksle inn et token som allerede er vekslet inn for mange ganger. |
invalid_request |
The audience in the subject token and the client with client_id '[client_id]' have different configuration owners. |
Actor client en annen konfigurasjonseier enn aud (API-ressursen) i subject token . |
Se også generelle feilmeldinger.
Utstedt Access-token
Ved vellykket Token Exchange vil actor client
få utstedt et Access-token.
Følgende claims vil være endret i det nye tokenet:
aud
: audience for API 2
Følgende claim identifiserer actor client
:
act
: Et sett av claims som identifiserer virksomhet og klient som opptrer på vegne av en autentisert person.act
-claimet er bygd opp som følger:- iss: HelseID STS som har identifisert
actor client
- client_id: identifikator for
actor client
helseid://claims/client/claims/orgnr_parent
: organisasjonsnummer for hovedenhethelseid://claims/client/claims/orgnr_child
: organisasjonsnummer for underenhet
- iss: HelseID STS som har identifisert
For kallkjeder der Token Exchange benyttes flere ganger, vil du få en nøstet struktur av act
-claims. Den innerste actor er den eldste, og den ytterste actor er den nyeste - og altså den aktive actor for det aktuelle Access-tokenet.
Følgende claim identifiserer subject client
:
helseid://claims/client/original_client_id
: klient-ID fra det førstesubject_token
i kjeden
Claims som blir kopiert fra subject_token
:
- Alle claims med prefiks
helseid://
sub
: HelseID-spesifikk identifikator for autentisert brukername
: Navn på brukeren som ble autentisertgiven_name
: Fornavn på brukeren som ble autentisertmiddle_name
: Mellomnavn på brukeren som ble autentisertfamily_name
: Etternavn på brukeren som ble autentisertsid
: Sesjons-ID for den innloggede brukerenidp
: IDP som ble brukt i forbindelse med autentisering av brukeramr
: innloggingsmetode i IDP som ble brukt i forbindelse med autentisering av brukerauth_time
: tidspunktet da brukeren ble autentisert
⚠️ Konsekvenser av dette (for API-eiere):
Claim som ikke finnes i det innkommende tokenet ( subject_token
), vil ikke være med i det nye tokenet, selv om API 2 har behov for denne informasjonen. Et eksempel på denne typen informasjon kan være claims som indikerer identiteten til en innlogget bruker.
Eksempel på et Access-token fra Token exchange
{
"alg": "RS256",
"kid": "78667F90DC11BF04BD9467D1F9120C4A4340B4CF",
"x5t": "eGZ_kNwRvwS9lGfR-RIMSkNAtM8",
"typ": "JWT"
}.{
"iss": "https://helseid-sts.test.nhn.no",
"nbf": 1713888289,
"iat": 1713888289,
"exp": 1713888889,
"aud": "nhn:helseid-public-samplecode",
"cnf": {
"jkt": "aoezvIe32RdFpTP4FIxwBYb6VGX0dp3ecvoVjFkdXQk"
},
"scope": [
"nhn:helseid-public-samplecode/client-credentials"
],
"amr": [
"pwd"
],
"client_id": "helseid-sample-token-exchange-actor-client",
"helseid://claims/client/original_client_id": "helseid-sample-token-exchange-subject-client",
"client_amr": "private_key_jwt",
"helseid://claims/identity/pid": "11857998857",
"helseid://claims/identity/security_level": "4",
"name": "VIRKELIG KJELTRING",
"jti": "25488FC67BAB3419DC6E70C273FBB871",
"sid": "0FAB2BC0164BF60B39ECED460E2A56BA",
"act": {
"iss": "https://helseid-sts.test.nhn.no",
"client_id": "helseid-sample-token-exchange-actor-client",
"helseid://claims/client/claims/orgnr_parent": "999977774"
},
"helseid://claims/client/claims/orgnr_parent": "999977774",
"oldsub": "LHcSgmD3Q/SO/0dLxXvhKBnh1ebeq61C3ndgEIkptbo=",
"sub": "vJs8Xr2F58spTNEPHM/a07KdZtSBGLQN9EmHuBGLy/c=",
"auth_time": 1713888282,
"idp": "testidp-oidc",
"helseid://claims/client/amr": "rsa_private_key",
"helseid://claims/client/client_name": "helseid-sample-token-exchange-actor-client",
"helseid://claims/client/client_tenancy": "single-tenant"
}.[Signature]