OpenID4VCI tunnistuse väljastamine selgitatud: pakkumisest vastuvõetud tunnistuseni
OpenID4VCI ehk OpenID for Verifiable Credential Issuance määratleb, kuidas rahakott taotleb ja saab väljastajalt tunnistuse. Üks väljastamine läbib mitu erinevat sammu, enne kui rahakotil on tegelikult kasutatav tunnistus, ja igal sammul on oma ebaõnnestumise viis. See leht käsitleb kogu seda elutsüklit algusest lõpuni, koos originaalsete läbitöötatud näidetega.
Kaks võimalust alustamiseks: eelautoriseeritud kood ja autoriseerimiskood
Väljastamine algab sageli väljastaja saadetud Credential Offer'ist ning selles nimetatud grant otsustab, kuidas rahakott autoriseeritakse. Rahakott saab väljastamise alustada ka ise, ilma pakkumiseta, kasutades autoriseerimiskoodi voogu. Mõlemad vood lõpevad samas kohas: rahakotil on juurdepääsutoken, mida ta saab kasutada tunnistuse taotlemiseks.
Eelautoriseeritud koodi voog
1. Väljastaja
Tunneb hoidjat juba, väljastab Credential Offer'i koos pre-authorized_code'iga
2. Rahakott
Lunastab koodi tokeni lõpp-punktis, valikuliselt koos tehingukoodiga
3. Rahakott
Taotleb tunnistust koos oma võtme valduse tõendiga
Autoriseerimiskoodi voog
1. Rahakott
Skannib Credential Offer'i, mis nimetab authorization_code granti, või alustab voogu ise ilma pakkumiseta
2. Autoriseerimisserver
Juhib hoidja läbi sisselogimise ja nõusoleku, seejärel väljastab koodi
3. Rahakott
Vahetab koodi tokeni vastu, seejärel taotleb tunnistust
Tunnistuse pakkumise kogu elutsükkel
Spetsifikatsioon ei määratle nimetatud olekuid, kuid väljastaja algatatud voogu, kus tunnistus väljastatakse kohe, on kõige lihtsam jälgida allpool oleva jadana. Iga samm võib ebaõnnestuda omal moel ja rahakoti rakendus peab käsitlema neid teid, mitte ainult õnnelikku teed.
Läbitöötatud näide: sõidukite tehnoülevaatuse tunnistus veoettevõttele
Sõidukite ülevaatuse asutus väljastab tehnoülevaatuse tunnistuse veoettevõtte ärirahakotti pärast tavapärast ülevaatust. Ülevaataja oli sõidukipargi juhi ülevaatuspunktis juba autentinud, seega kasutab väljastaja eelautoriseeritud koodi voogu. Alltoodud sammud järgivad seda ühte väljastamist pakkumisest vastuvõetud tunnistuseni.
Näide kirjeldab OpenID4VCI põhiversiooni. Kõrge kindlustatuse juurutused, nagu EUDI Wallet, kasutavad selle peal HAIP profiili, mis lisab DPoP-iga seotud juurdepääsutokenid, rahakoti atesteerimise tokeni lõpp-punktis ja tunnistuse võtmete atesteerimise. Need on siin selguse huvides välja jäetud.
1. Tunnistuse pakkumine
Ülevaatusasutuse terminal kuvab QR-koodi. See sisaldab URI-t, mis algab openid-credential-offer://, ja mis kannab allpool olevat pakkumist URL-kodeerituna credential_offer parameetris, või credential_offer_uri väärtust, millelt rahakott selle toob. Rahakott skannib koodi ja loeb, milline tunnistus on pakkumisel ning kuidas seda saada.
Väljastaja
Kuvab QR-koodi koos Credential Offer'iga
Nimetab tunnistuse konfiguratsiooni ja pre-authorized_code granti
{
"credential_issuer": "https://issuer.fleetinspect.example",
"credential_configuration_ids": ["roadworthiness_certificate"],
"grants": {
"urn:ietf:params:oauth:grant-type:pre-authorized_code": {
"pre-authorized_code": "fi-8f2c0b3a",
"tx_code": {
"length": 6,
"input_mode": "numeric",
"description": "Enter the code sent to your phone by text message"
}
}
}
}2. Väljastaja metaandmete avastamine
Enne mistahes taotlemist toob rahakott väljastaja metaandmed, et teada saada, mida roadworthiness_certificate sisaldab ja milliseid lõpp-punkte kutsuda. Metaandmed ei loetle eraldi autoriseerimisservereid, seega on väljastaja ise oma autoriseerimisserver ning rahakott loeb tokeni lõpp-punkti selle serveri metaandmetest.
Rahakott
GET /.well-known/openid-credential-issuer
Saab teada tunnistuse vormingu, väited ja aktsepteeritud tõendi tüübid, samuti nonce, tunnistuse, edasilükkamise ja teavituse lõpp-punktid
Tunnistuse väljastaja metaandmed (väljavõte)
{
"credential_issuer": "https://issuer.fleetinspect.example",
"nonce_endpoint": "https://issuer.fleetinspect.example/nonce",
"credential_endpoint": "https://issuer.fleetinspect.example/credential",
"deferred_credential_endpoint": "https://issuer.fleetinspect.example/deferred",
"notification_endpoint": "https://issuer.fleetinspect.example/notify",
"credential_configurations_supported": {
"roadworthiness_certificate": {
"format": "dc+sd-jwt",
"vct": "https://fleetinspect.example/vct/roadworthiness",
"cryptographic_binding_methods_supported": ["jwk"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_metadata": {
"claims": [
{ "path": ["vehicle_registration"] },
{ "path": ["inspection_result"] },
{ "path": ["valid_until"] }
]
}
}
}
}Autoriseerimisserveri metaandmed (väljavõte), lehelt /.well-known/oauth-authorization-server
{
"issuer": "https://issuer.fleetinspect.example",
"token_endpoint": "https://issuer.fleetinspect.example/token",
"pre-authorized_grant_anonymous_access_supported": true
}3. Tokeni taotlus
Rahakott lunastab eelautoriseeritud koodi tokeni lõpp-punktis koos tehingukoodiga, mille ülevaatusasutus saatis sõidukipargi juhi telefonile. Selle koodi saatmine teise kanali kaudu tähendab, et keegi, kes pildistab QR-koodi õla tagant, ei saa seda ikkagi lunastada.
Rahakott
POST /token
Saadab pre-authorized_code ja tx_code, saab juurdepääsutokeni, mis kehtib ainult selle pakkumise kohta
POST /token HTTP/1.1 Host: issuer.fleetinspect.example Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code &pre-authorized_code=fi-8f2c0b3a &tx_code=482913
Vastus
{
"access_token": "fi-at-3d91e0",
"token_type": "Bearer",
"expires_in": 86400
}4. Valduse tõend
Kuna metaandmed loetlevad nonce_endpoint'i, toob rahakott sealt kõigepealt värske c_nonce. Seejärel tõendab ta, et omab privaatvõtit, millega tunnistus seotakse, allkirjastades proof JWT väljastaja identifikaatori ja selle c_nonce peale.
Rahakott
POST /nonce, seejärel allkirjastab proof JWT võtmega, millega tunnistus seotakse
Seob tunnistuse selle võtmega, mitte ainult juurdepääsutokeni omanikuga
POST /nonce HTTP/1.1 Host: issuer.fleetinspect.example
Vastus
{
"c_nonce": "fi-nonce-77aa"
}Rahakott ehitab nüüd proof JWT kahest JSON-objektist, päisest ja sisust, ning allkirjastab need privaatvõtmega, millega tunnistus seotakse.
Päis: mis see JWT on ja milline võti selle allkirjastas
{
"typ": "openid4vci-proof+jwt",
"alg": "ES256",
"jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." }
}typ: märgib selle OpenID4VCI võtme tõendiks, nii et seda ei saa segi ajada ühegi muu JWT liigigaalg: allkirjastamisalgoritm, üks neist, mille väljastaja loetles proof_signing_alg_values_supported väärtusesjwk: avalik võti, millega tunnistus seotakse; väljastaja kontrollib allkirja selle põhjal
Sisu: kelle jaoks tõend on ja millal see loodi
{
"aud": "https://issuer.fleetinspect.example",
"iat": 1789376400,
"nonce": "fi-nonce-77aa"
}aud: väljastaja identifikaator, nii et tõendit ei saa teise väljastaja juures uuesti kasutadaiat: tõendi loomise aeg, sekundites alates 1970. aastastnonce: nonce lõpp-punktist saadud c_nonce, mis näitab, et tõend on värske
Allkirjastatud tulemus
Päis ja sisu on mõlemad base64url-kodeeritud ja ühendatud punktiga. Rahakott allkirjastab selle stringi oma privaatvõtmega ja lisab base64url-kodeeritud allkirja pärast teist punkti. Tulemuseks olev string on proof JWT, mille rahakott saadab tunnistuse taotluses sammus 5.
base64url(header) . base64url(payload) . base64url(signature) eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIs... .eyJhdWQiOiJodHRwczovL2lzc3Vlci5mbGVldGluc3BlY3QuZXhhbXBsZSIs... .<ES256 signature>
5. Tunnistuse taotlus
Rahakott kutsub tunnistuse lõpp-punkti koos juurdepääsutokeni ja tõendiga ning väljastaja loob ja tagastab allkirjastatud tunnistuse.
Rahakott
POST /credential
Saadab juurdepääsutokeni, konfiguratsiooni ID ja proof JWT, saab allkirjastatud tunnistuse ja notification_id
POST /credential HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0
{
"credential_configuration_id": "roadworthiness_certificate",
"proofs": {
"jwt": ["<proof JWT from step 4>"]
}
}Vastus
{
"credentials": [
{ "credential": "<issuer-signed SD-JWT VC>" }
],
"notification_id": "fi-notif-9012"
}Kogu voog ühe pilguga
See jadadiagramm ühendab näite viis sammu tervikuks, pakkumisest teavituseni. Pidevad nooled on taotlused, katkendlikud nooled on vastused ning punktiirnool on tehingukood, mis liigub protokollivälisel teel SMS-sõnumina.
Rahakott
Veoettevõtte ärirahakott
Autoriseerimisserver
Selles näites käitab väljastaja ise
Tunnistuse väljastaja
Sõidukite ülevaatuse asutus
- Tunnistuse väljastaja juurde Rahakott: Credential Offer, kuvatud QR-koodina
- Tunnistuse väljastaja juurde Rahakott: tx_code, saadetud SMS-iga sõidukipargi juhi telefonile
- Rahakott juurde Tunnistuse väljastaja: GET /.well-known/openid-credential-issuer
- Tunnistuse väljastaja juurde Rahakott: tunnistuse väljastaja metaandmed
- Rahakott juurde Autoriseerimisserver: GET /.well-known/oauth-authorization-server
- Autoriseerimisserver juurde Rahakott: autoriseerimisserveri metaandmed
- Rahakott juurde Autoriseerimisserver: POST /token: pre-authorized_code, tx_code
- Autoriseerimisserver juurde Rahakott: access_token
- Rahakott juurde Tunnistuse väljastaja: POST /nonce
- Tunnistuse väljastaja juurde Rahakott: c_nonce
- Rahakott: allkirjastab proof JWT
- Rahakott juurde Tunnistuse väljastaja: POST /credential: juurdepääsutoken, tõendid
- Tunnistuse väljastaja juurde Rahakott: credentials, notification_id
- Rahakott: valideerib ja salvestab
- Rahakott juurde Tunnistuse väljastaja: POST /notify: credential_accepted
- Tunnistuse väljastaja juurde Rahakott: 204 No Content
Kui tunnistus pole veel valmis: edasilükatud väljastamine
Ülaltoodud näide eeldab, et ülevaatuse tulemus on juba lõplik. Kui ülevaatusasutus peab hoopis eskaleerima piiripealse tulemuse vanemülevaatajale, ei saa tunnistuse lõpp-punkt tunnistust kohe tagastada, seega lükkab ta väljastamise edasi.
Viivitamatu väljastamine
Tunnistuse lõpp-punkt tagastab allkirjastatud tunnistuse samas vastuses kui taotlus.
Edasilükatud väljastamine
Tunnistuse lõpp-punkt vastab HTTP 202, transaction_id ja intervalliga tunnistuse asemel. Rahakott küsitleb deferred_credential_endpoint'i selle ID-ga, oodates taotluste vahel vähemalt intervalliga määratud arvu sekundeid, kuni tunnistus on valmis.
Edasilükatud vastus /credential'ist
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"transaction_id": "fi-tx-55c2",
"interval": 900
}/deferred küsitlemine, kuni see on valmis
POST /deferred HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0
{ "transaction_id": "fi-tx-55c2" }
// While the review is open: 202 with the same transaction_id and interval.
// Once approved: 200 with the credentials, optionally with a notification_id.
// If the review rejects the result: a credential_request_denied error.Ringi sulgemine: teavituse lõpp-punkt
Pärast väljastamist saab rahakott väljastajale öelda, mis tunnistusega juhtus, kasutades tunnistuse vastusest saadud notification_id'd. Rahakotid ei ole kohustatud neid teavitusi saatma ja kohaletoimetamine ei ole tagatud, seega ei saa väljastaja puuduva teavituse põhjal midagi järeldada.
Rahakott
Saadab sündmuse väljastaja notification_endpoint'ile saadud notification_id kohta, mis hõlmab kõiki selles vastuses olevaid tunnistusi
Salvestatud rahakotti
Väljastamine ebaõnnestus mõnel muul põhjusel, näiteks tunnistus ei läbinud valideerimist
Väljastamine ebaõnnestus hoidja tõttu, näiteks keeldus ta seda salvestamast
POST /notify HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0
{
"notification_id": "fi-notif-9012",
"event": "credential_accepted"
}Seotud mõisted
Korduma kippuvad küsimused
Kuidas rahakott teab, millist granti tüüpi kasutada?
Credential Offer nimetab granti oma grants-objektis. authorization_code on olemas, kui väljastaja soovib, et hoidja logiks voo osana sisse. pre-authorized_code on olemas, kui hoidja oli juba autenditud kanalil, kus pakkumine loodi, näiteks alltoodud näites ülevaataja poolt ülevaatuspunktis. Pakkumine võib loetleda mõlemad ja rahakott valib siis ühe. Kui pakkumisel pole grants-objekti üldse, otsib rahakott metaandmetest, milliseid granditüüpe autoriseerimisserver toetab.
Miks rahakott toob väljastaja metaandmed enne mistahes taotlemist?
Credential Offer nimetab ainult credential_configuration_ids väärtused, väljastaja URL-i ja grants. Väljastaja metaandmed, mida pakutakse tuntud tee kaudu, kirjeldavad iga konfiguratsiooni: selle vormingut, väiteid ja aktsepteeritud tõendi tüüpe, samuti nonce, tunnistuse, edasilükkamise ja teavituse lõpp-punkte. Need näitavad ka, millist autoriseerimisserverit kasutada, ja selle serveri enda metaandmed annavad tokeni lõpp-punkti. Ilma mõlemata ei teaks rahakott, kuidas ehitada kehtivaid taotlusi ega mida hoidjale enne nõusoleku andmist näidata.
Mida valduse tõend tegelikult tõendab?
See tõendab, et tunnistust taotlev rahakott omab privaatvõtit, millega tunnistus seotakse, mitte ainult seda, et tal on kehtiv juurdepääsutoken. Rahakott allkirjastab proof JWT väljastaja identifikaatori ja väljastaja nonce lõpp-punktist saadud värske c_nonce peale, kasutades seda võtit. Väljastaja lisab vastava avaliku võtme tunnistusse. Kontrollija, kes nõuab võtmega sidumist, palub hoidjal esitamisel uuesti sama võtmega allkirjastada, nii et kopeeritud tunnistus ilma võtmeta seda kontrolli ei läbi.
Miks väljastaja lükkaks väljastamise edasi, selle asemel et tunnistus kohe tagastada?
Mõned kontrollid, mida väljastaja teeb enne tunnistuse loomist, ei saa lõppeda ühe HTTP-taotluse jooksul, näiteks käsitsi ülevaatus või aeglase välise registri päring. Edasilükatud väljastamine võimaldab tunnistuse lõpp-punktil vastata kohe transaction_id'ga, selle asemel et ühendust blokeerida, ning rahakott küsitleb edasilükatud lõpp-punkti selle ID-ga, kuni kontroll lõpeb ja tunnistus on valmis kättesaamiseks.
Kas teavituse lõpp-punkt on väljastajale kohustuslik rakendada?
Ei. See on väljastajatele valikuline ja ka rahakotid ei ole kohustatud seda kasutama. Kui mõlemad seda toetavad, saab väljastaja teada, mis pärast väljastamist juhtus: tunnistused salvestati (credential_accepted), hoidja peatas väljastamise, näiteks keeldudes neid salvestamast (credential_deleted), või see ebaõnnestus mõnel muul põhjusel (credential_failure). Kohaletoimetamine ei ole tagatud, seega peaks väljastaja käsitlema teavitust kasuliku teabena, mitte kunagi usaldusväärse kirjena, ega tohi puuduva teavituse põhjal midagi järeldada.
Allikad
See leht on informatiivne ega kujuta endast õigusnõustamist. Ametliku juhise saamiseks pöörduge otse OpenID Foundationi ja Euroopa Komisjoni poole.