ã¦ã§ãèªè¨¼ API
Baseline
åºãå©ç¨å¯è½
*
ãã®æ©è½ã¯åºãå®è£ ããã¦ãããå¤ãã®ãã¼ã¸ã§ã³ã®ç«¯æ«ããã©ã¦ã¶ã¼ã§åä½ãã¾ãã2021å¹´9æä»¥éããã¹ã¦ã®ãã©ã¦ã¶ã¼ã§å©ç¨å¯è½ã§ãã
* ãã®æ©è½ã®ä¸é¨ã¯ã対å¿ã¬ãã«ãç°ãªãå ´åãããã¾ãã
å®å ¨ãªã³ã³ããã¹ãç¨: ãã®æ©è½ã¯ä¸é¨ã¾ãã¯ãã¹ã¦ã®å¯¾å¿ãã¦ãããã©ã¦ã¶ã¼ã«ããã¦ãå®å ¨ãªã³ã³ããã¹ã (HTTPS) ã§ã®ã¿å©ç¨ã§ãã¾ãã
ã¦ã§ãèªè¨¼ API (WebAuthn) ã¯ãå ¬é鵿å·ãç¨ãã¦å¼·åãªèªè¨¼ãå¯è½ã«ããè³æ ¼æ å ±ç®¡ç API ã®æ¡å¼µæ©è½ã§ããã¹ã¯ã¼ãã¬ã¹èªè¨¼ãã SMS ããã¹ããç¨ããªãå®å ¨ãªå¤è¦ç´ èªè¨¼ (MFA) ãå®ç¾ãã¾ãã
WebAuthn ã®æ¦å¿µã¨ä½¿ãæ¹
ã¦ã§ãèªè¨¼ API (WebAuthn) ã¯ããã¹ã¯ã¼ãã SMS ã®ããã¹ãã使ç¨ããã®ã§ã¯ãªããå ¬é鵿å·ã使ç¨ãã¦ãã¦ã§ããµã¤ãã§ç»é²ãèªè¨¼ãå¤è¦ç´ èªè¨¼ãè¡ãã¾ããããã«ã¯ããã¤ãã®å©ç¹ãããã¾ãã
- ãã£ãã·ã³ã°ããã®ä¿è·: å½ã®ãã°ã¤ã³ãµã¤ãã使ããæ»æè ã¯ãã¦ã¼ã¶ã¼ã¨ãã¦ãã°ã¤ã³ãããã¨ãã§ãã¾ããããµã¤ãã®ãªãªã¸ã³ã§ç½²åãå¤ããããã§ãã
- æ å ±æ¼æ´©ã®å½±é¿ã軽æ¸: éçºè ã¯å ¬ééµãããã·ã¥åããå¿ è¦ãããã¾ãããæ»æè ãèªè¨¼ã«ä½¿ç¨ããå ¬ééµã«ã¢ã¯ã»ã¹ãã¦ããç§å¯éµãå¿ è¦ãªããèªè¨¼ãã§ããªãããã§ãã
- ãã¹ã¯ã¼ãæ»æãç¡å¹ï¼ ã¦ã¼ã¶ã¼ã«ãã£ã¦ã¯ãã¹ã¯ã¼ããåå©ç¨ããå¯è½æ§ããããæ»æè ã¯å¥ã®ã¦ã§ããµã¤ãç¨ã«ã¦ã¼ã¶ã¼ã®ãã¹ã¯ã¼ããï¼ä¾ãã°ããã¼ã¿æ¼æ´©ãä»ãã¦ï¼åå¾ããå¯è½æ§ãããã¾ããã¾ããããã¹ãã®ãã¹ã¯ã¼ãã¯ããã¸ã¿ã«ç½²åãããç·å½ãããã¯ããã«å®¹æã§ãã
å¤ãã®ã¦ã§ããµã¤ãã«ã¯æ¢ã«ãã¦ã¼ã¶ã¼ãæ°è¦ã¢ã«ã¦ã³ããç»é²ãããæ¢åã¢ã«ã¦ã³ãã«ãã°ã¤ã³ãããã§ãããã¼ã¸ãåå¨ãã¾ãã WebAuthn ã¯ããã®ã·ã¹ãã ã®èªè¨¼é¨åãç½®ãæããããå¼·åãããããå½¹å²ãæããã¾ããããã¯è³æ ¼æ å ±ç®¡ç API ãæ¡å¼µããã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¨èªè¨¼å¨ (authenticator) ã®éã®ããã¨ããæ½è±¡åããã¨ã¨ãã«ã以ä¸ã®æ°æ©è½ãæä¾ãã¾ãã
navigator.credentials.create()ãpublicKeyãªãã·ã§ã³ä»ãã§ä½¿ç¨ããã¨ãã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯èªè¨¼å¨ãéãã¦æ°ããªè³æ ¼æ å ±ãçæãã¾ããæ°ããã¢ã«ã¦ã³ãã®ç»é²ãã¾ãã¯æ¢åã®ã¢ã«ã¦ã³ãã¸ã®æ°ããé対称éµãã¢ã®é¢é£ä»ãã®ããã«ãããè¡ãã¾ãã- æ°ããã¢ã«ã¦ã³ããç»é²ããéããããã®è³æ ¼æ å ±ã¯ãµã¼ãã¼ï¼ãµã¼ãã¹ã¾ãã¯èªè¨¼ä¾é ¼è ï¼ä»¥ä¸ RPãrelying partyï¼ã¨ãå¼ã°ããï¼ã«ç»é²ãããã®ã¡ã®ãã°ã¤ã³ã§ä½¿ç¨ãããã¨ãã§ãã¾ãã
- é対称éµãã¢ã¯èªè¨¼å¨ã«ä¿åããããããä¾ãã°å¤è¦ç´ èªè¨¼ (MFA) ã®éã«ãã¦ã¼ã¶ã¼ã RP ã§èªè¨¼ããããã«ä½¿ç¨ãããã¨ãã§ãã¾ããèªè¨¼å¨ã¯ Windows Hello ãªã©ã®ããã« OS ã«çµã¿è¾¼ããã¨ãã§ãã¾ããã USB ã Bluetooth ã»ãã¥ãªãã£ãã¼ãªã©ã®ç©ççãªãã¼ã¯ã³æ©å¨ã¨ãããã¨ãã§ãã¾ãã
navigator.credentials.get()ãpublicKeyãªãã·ã§ã³ä»ãã§ä½¿ç¨ããã¨ãã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯æ¢åã®è³æ ¼æ å ±ä¸å¼ããRP ã®èªè¨¼ã«ä½¿ç¨ãã¾ãï¼åè¿°ã®ããã«ããã©ã¤ããªãã°ã¤ã³ã¨ãã¦ãã¾ã㯠MFA ã«ããã追å è¦ç´ ã®æä¾ã¨ãã¦ï¼ã
æãåºæ¬çãªå½¢ã¨ãã¦ã¯ãcreate() 㨠get() ã®ä¸¡æ¹ããããã£ã¬ã³ã¸ãã¨å¼ã°ããã¨ã¦ã大ããªä¹±æ°ããµã¼ãã¼ããåãåããç§å¯éµã«ãã£ã¦ç½²åããããã£ã¬ã³ã¸ããµã¼ãã¼ã«è¿ãã¾ããããã¯ããããã¯ã¼ã¯ä¸ã§ç§å¯æ
å ±ãä¸åæ¼ãããã¨ãªããã¦ã¼ã¶ã¼ãèªè¨¼ã«å¿
è¦ãªç§å¯éµãä¿æãã¦ãããã¨ããµã¼ãã¼ã«è¨¼æãããã¨ãã§ãã¾ãã
ã¡ã¢: ããã£ã¬ã³ã¸ãã¯ãå°ãªãã¨ã 16 ãã¤ãã®ãµã¤ãºã®ã©ã³ãã ãªæ å ±ã®ãããã¡ã¼ã§ãªããã°ãªãã¾ããã
éµãã¢ã®çæã¨ã¦ã¼ã¶ã¼ã®ç»é²
è³æ ¼æ å ±ã®ä½æããã»ã¹ãã©ã®ããã«æ©è½ãããã説æããããã«ãã¦ã¼ã¶ã¼ã RP ã«å¯¾ãã¦è³æ ¼æ å ±ãç»é²ãããã¨ããéã«çºçããä¸è¬çãªæµãã以ä¸ã«è¨è¿°ãã¾ãã
-
RP ãµã¼ãã¼ã¯ãé©åãªä¿è·ãããä»çµã¿ï¼ãã§ããã XMLHttpRequest ãªã©ï¼ã使ç¨ãã¦ãã¦ã¼ã¶ã¼æ å ±ã¨RP æ å ±ããç»é²å¦çãæ å½ããã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ã«ããã£ã¬ã³ã¸ãã¨å ±ã«éä¿¡ãã¾ãã
ã¡ã¢: RP ãµã¼ãã¼ã¨ã¦ã§ãã¢ããªã±ã¼ã·ã§ã³éã§æ å ±ãå ±æããå½¢å¼ã¯ãã¢ããªã±ã¼ã·ã§ã³æ¬¡ç¬¬ã§ãã æ¨å¥¨ãããæ¹æ³ã¯ãè³æ ¼æ å ±ããã³è³æ ¼æ å ±ãªãã·ã§ã³ã«å¯¾ã㦠JSON å表ç¾ãªãã¸ã§ã¯ãã交æãããã¨ã§ãã
PublicKeyCredentialã«ã¯ãJSON 表ç¾ããèªè¨¼ API ã§è¦æ±ãããå½¢å¼ã¸ã®å¤æãè¡ãããã®ä¾¿å©ãªã¡ã½ãããç¨æããã¦ãã¾ããparseCreationOptionsFromJSON()ãparseRequestOptionsFromJSON()ãPublicKeyCredential.toJSON()ã§ãã -
ã¦ã§ãã¢ããªã¯ãRP 代ããã«ã
navigator.credentials.create()å¼ã³åºããéãã¦ãèªè¨¼å¨ã«ããæ°ããèªè¨¼æ å ±ã®çæãéå§ãã¾ãããã®å¼ã³åºãã«ã¯publicKeyãªãã·ã§ã³ã渡ããã端æ«ã®æ©è½ï¼çä½èªè¨¼ãªã©ã«ããç¬èªã®ã¦ã¼ã¶ã¼èªè¨¼ãæä¾ãããã©ãããªã©ï¼ãæå®ãã¾ããä¸è¬çãª
create()å¼ã³åºãã¯ã次ã®ãããªãã®ã«ãªãã¾ããjslet credential = await navigator.credentials.create({ publicKey: { challenge: new Uint8Array([117, 61, 252, 231, 191, 241 /* ⦠*/]), rp: { id: "acme.com", name: "ACME Corporation" }, user: { id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]), name: "jamiedoe", displayName: "Jamie Doe", }, pubKeyCredParams: [{ type: "public-key", alg: -7 }], }, });create()å¼ã³åºãã®å¼æ°ã¯ãæ¹ãã鲿¢ã®ãããç½²åããã SHA-256 ããã·ã¥ã¨å ±ã«èªè¨¼å¨ã«æ¸¡ããã¾ãã -
èªè¨¼å¨ã¯ã¦ã¼ã¶ã¼ã®åæãåå¾ããå¾ãéµãã¢ãçæããå ¬ééµã¨ãªãã·ã§ã³ã®ç½²åä»ãã¢ãã¹ãã¼ã·ã§ã³ (attestation) ãã¦ã§ãã¢ããªã«è¿ãã¾ããããã¯ã
create()å¼ã³åºããè¿ãPromiseãå±¥è¡ãããéã«ãPublicKeyCredentialãªãã¸ã§ã¯ãã¤ã³ã¹ã¿ã³ã¹ã®å½¢å¼ã§æä¾ããã¾ãï¼PublicKeyCredential.responseããããã£ã«ã¯ã¢ãã¹ãã¼ã·ã§ã³ãå«ã¾ãã¾ãï¼ã -
ã¦ã§ãã¢ããªã¯ãé©åãªä»çµã¿ã使ç¨ãã¦å度ã
PublicKeyCredentialã RP ãµã¼ãã¼ã«è»¢éãã¾ãã -
RP ãµã¼ãã¼ã¯ãå ¬ééµã¨ã¦ã¼ã¶ã¼ ID ãçµã¿åããã¦ä¿åããå°æ¥ã®èªè¨¼ã®ããã«è³æ ¼æ å ±ãè¨æ¶ãã¾ãããã®ããã»ã¹ã®ä¸ã§ãç»é²ãå®å ¨ã«è¡ããæ¹ããããã¦ããªããã¨ã確èªããããã®ä¸é£ã®ãã§ãã¯ãå®è¡ãã¾ããããã«ã¯ä»¥ä¸ã®ãã®å«ã¾ãã¾ãã
- éä¿¡ããããã£ã¬ã³ã¸ã¨åä¸ã®ãã£ã¬ã³ã¸ã§ãããã¨ã確èªããã
- ãªãªã¸ã³ãæ³å®ããããªãªã¸ã³ã§ãããã¨ã確èªããã
- ç½²åããã³ã¢ãã¹ãã¼ã·ã§ã³ããæåã®å ´é¢ã§éµãã¢ãçæããããã«èªè¨¼å¨ã®ç¹å®ã®ã¢ãã«ã«å¯¾ãã¦ãæ£ããè¨¼ææ¸ãã§ã¼ã³ã使ç¨ãã¦ãããã¨ãæ¤è¨¼ããã
è¦å: ã¢ãã¹ãã¼ã·ã§ã³ã¯ãRP ãèªè¨¼å¨ã®åºæã夿ããææ®µãæä¾ãã¾ããRP ã¯ãèªè¨¼å¨ã®è¨±å¯ãªã¹ããä¿æãããã¨ãã¹ãã§ã¯ããã¾ããã
ã¦ã¼ã¶ã¼ã®èªè¨¼
ã¦ã¼ã¶ã¼ã WebAuthn ã«ç»é²ããããããµã¼ãã¹ã«å¯¾ãã¦èªè¨¼ï¼ãã°ã¤ã³ï¼ãè¡ããã¨ãã§ãã¾ããèªè¨¼ããã¼ã¯ç»é²ããã¼ã¨é¡ä¼¼ãã¦ãã¾ããã主ãªéãã¯ä»¥ä¸ã®éãã§ãã
- ã¦ã¼ã¶ã¼ã¾ã㯠RP ã®æ å ±ãå¿ è¦ã¨ããªãã
- èªè¨¼å¨ã®éµãã¢ã§ã¯ãªãããµã¼ãã¹ç¨ã«äºåã«çæãããéµãã¢ã使ç¨ãã¦ã¢ãµã¼ã·ã§ã³ã使ããã
ä¸è¬çãªèªè¨¼ããã¼ã¯ä»¥ä¸ã®éãã§ãã
-
RP ã¯ããã£ã¬ã³ã¸ããçæããRP ããã³ã¦ã¼ã¶ã¼ã®è³æ ¼æ å ±ã®ãªã¹ãã¨å ±ã«ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¸ãé©åãªä¿è·ãããæ©æ§ãç¨ãã¦éä¿¡ãããã¾ããè³æ ¼æ å ±ã®æ¤ç´¢å ãä¾ãã°ãã¼ã«ã«å èµèªè¨¼å¨ãUSB ã BLE çµç±ã®å¤é¨èªè¨¼å¨ãªã©ãæå®ãããã¨ãã§ããã
-
ãã©ã¦ã¶ã¼ã¯
navigator.credentials.get()å¼ã³åºããä»ãã¦ãèªè¨¼å¨ã«ãã£ã¬ã³ã¸ã®ç½²åãä¾é ¼ãããã®éã«publicKeyãªãã·ã§ã³ã§è¨¼ææ¸ã渡ããä¸è¬çãª
get()å¼ã³åºãã¯æ¬¡ã®ããã«ãªãã¾ããjslet credential = await navigator.credentials.get({ publicKey: { challenge: new Uint8Array([139, 66, 181, 87, 7, 203 /* ⦠*/]), rpId: "acme.com", allowCredentials: [ { type: "public-key", id: new Uint8Array([64, 66, 25, 78, 168, 226, 174 /* ⦠*/]), }, ], userVerification: "required", }, });get()å¼ã³åºãã®å¼æ°ã¯ãèªè¨¼ãå¦çããããã«èªè¨¼å¨ã«æ¸¡ããã¾ãã -
èªè¨¼å¨ãæå®ãããè³æ ¼æ å ±ã®ãããããå«ã¿ããã¤ãã£ã¬ã³ã¸ã¸ã®ç½²åãæåããå ´åãã¦ã¼ã¶ã¼ã®åæãå¾ãå¾ãç½²åä»ãã¢ãµã¼ã·ã§ã³ãã¦ã§ãã¢ããªã«è¿ããããã¯ã
get()å¼ã³åºããè¿ãPromiseãå±¥è¡ãããéã«ãPublicKeyCredentialãªãã¸ã§ã¯ãã¤ã³ã¹ã¿ã³ã¹ã®å½¢å¼ã§æä¾ãããï¼PublicKeyCredential.responseããããã£ã«ã¢ãµã¼ã·ã§ã³æ å ±ãå«ã¾ããï¼ã -
ã¦ã§ãã¢ããªã¯ç½²åä»ãã¢ãµã¼ã·ã§ã³ã RP ãµã¼ãã¼ã«è»¢éããRP ãæ¤è¨¼ãã¾ãããã®æ¤è¨¼ã§ã¯ä»¥ä¸ã®ç¹ããã§ãã¯ãã¾ãã
- ç»é²ãªã¯ã¨ã¹ãæã«ä¿åãããå ¬ééµã使ç¨ãã¦ãèªè¨¼å¨ã«ããç½²åãæ¤è¨¼ããã
- èªè¨¼è ãç½²åãããã£ã¬ã³ã¸ãããµã¼ãã¼ã«ãã£ã¦çæããããã£ã¬ã³ã¸ã¨ä¸è´ãããã¨ã確èªããã
- ãã®ãµã¼ãã¹ã«å¯¾ãã¦æå¾ ããã RP ã® ID ã§ãããã¨ã確èªããã
-
ãµã¼ãã¼ã«ããæ¤è¨¼ãå®äºããã¨ãèªè¨¼ããã¼ã¯æåã¨è¦ãªããã¾ãã
æ¤åºå¯è½ãªè³æ ¼æ å ±ã¨æ¡ä»¶ä»ã仲ä»
æ¤åºå¯è½ãªè³æ ¼æ å ±ã¯ãèªè¨¼å¨ããåå¾ããã¾ãï¼ãã©ã¦ã¶ã¼ã«ãã£ã¦æ¤åºããã¾ãï¼ãããã¯ãã¦ã¼ã¶ã¼ã RP ã®ã¦ã§ãã¢ããªã«ãã°ã¤ã³ããéã®ãã°ã¤ã³ãªãã·ã§ã³ã¨ãã¦æä¾ããã¾ããããã«å¯¾ããæ¤åºå¯è½ã§ãªãè³æ ¼æ å ±ã¯ãRP ã®ãµã¼ãã¼ã«ãã£ã¦æä¾ããããã©ã¦ã¶ã¼ããã°ã¤ã³ãªãã·ã§ã³ã¨ãã¦æç¤ºãã¾ãã
æ¤åºå¯è½ãªè³æ ¼æ
å ± ID ããã³ã¦ã¼ã¶ã¼åã表示åãªã©ã®é¢é£ã¡ã¿ãã¼ã¿ã¯ããã©ã¦ã¶ã¼ã®ãã¹ã¯ã¼ãããã¼ã¸ã£ã¼ã èªè¨¼ã¢ããªããã¼ãã¦ã§ã¢ã½ãªã¥ã¼ã·ã§ã³ï¼YubiKey ãªã©ï¼ã¨ãã£ãã¯ã©ã¤ã¢ã³ãå´ã®èªè¨¼å¨ã«æ ¼ç´ããããã«ä¿åããã¾ãããã®æ
å ±ãèªè¨¼å¨ã§å©ç¨ã§ããç¶æ
ã«ãããã¨ã§ãã¦ã¼ã¶ã¼ã¯è³æ ¼æ
å ±ãå
¥åããã«ä¾¿å©ã«ãã°ã¤ã³ã§ãããããã®è³æ ¼æ
å ±ãã¢ãµã¼ã·ã§ã³ããéã«ãRP 㯠credentialId ãæä¾ããå¿
è¦ãæã¡ã¾ããï¼ãã ããå¿
è¦ã«å¿ãã¦æä¾ãããã¨ã¯å¯è½ã§ããRP ãè³æ ¼æ
å ±ãã¢ãµã¼ã·ã§ã³ããå ´åã¯ãæ¤åºå¯è½ã§ãªãã¯ã¼ã¯ããã¼ã«å¾ãã¾ãï¼ã
æ¤åºå¯è½ãªè³æ ¼æ
å ±ã¯ãcreate() ã®å¼ã³åºãã§ residentKey ãæå®ãããã¨ã§ä½æããã¾ããæ°ããè³æ ¼æ
å ±ã®credentialIdãã¦ã¼ã¶ã¼ã¡ã¿ãã¼ã¿ãå
¬ééµã¯ãåè¿°ã®ããã«èªè¨¼å¨ã«æ ¼ç´ãããã ãã§ãªããã¦ã§ãã¢ããªã«ãè¿ããã RP ãµã¼ãã¼ã«ä¿åããã¾ãã
èªè¨¼ã«ããã¦ã RP ãµã¼ãã¼ã¯æ¡ä»¶ä»ã仲ä»ãæå®ã㦠get() ãå¼ã³åºãéã«æ¡ä»¶ä»ã仲ä»ãæå®ãã¾ããå
·ä½çã«ã¯ãmediation ã conditional ã«è¨å®ãã空㮠allowCredentials ãªã¹ãï¼ã¤ã¾ããæ¤åºå¯è½ãªè³æ ¼æ
å ±ã®ã¿ã表示å¯è½ã§ããã¨ãããã¨ï¼ãããã³ãã£ã¬ã³ã¸ãæå®ãã¾ãã
æ¡ä»¶ä»ã仲ä»ã§ã¯ãèªè¨¼å¨ã§å¾ãããæ¤åºå¯è½ãªè³æ ¼æ
å ±ããè³æ ¼æ
å ±ãè¦æ±ãã¦ãããªãªã¸ã³ã¨ã¨ãã«ãã¢ã¼ãã«ãã¤ã¢ãã°ã§ã¯ãªãéã¢ã¼ãã« UI ã§ã¦ã¼ã¶ã¼ã«è¡¨ç¤ºã¾ããå
·ä½çã«ã¯ããã°ã¤ã³ãã©ã¼ã ã§å©ç¨ã§ããèªè¨¼æ
å ±ãèªåå
¥åããã¨ãããã¨ã§ããæ¤åºå¯è½ãªè³æ ¼æ
å ±ã«ä¿åãããã¡ã¿ãã¼ã¿ã¯ãã¦ã¼ã¶ã¼ããã°ã¤ã³æã«è³æ ¼æ
å ±ã鏿ããããã®åèã«ãªããã表示ã§ãã¾ãããã°ã¤ã³ãã©ã¼ã ã§æ¤åºå¯è½ãªè³æ ¼æ
å ±ã表示ããã«ã¯ããã©ã¼ã ãã£ã¼ã«ãã« autocomplete="webauthn" ãåæã«è¨è¼ããå¿
è¦ãããã¾ãã
ç¹°ãè¿ãã¾ãããRP ã¯èªè¨¼å¨ã«ãä½ã®è³æ ¼æ
å ±ãã¦ã¼ã¶ã¼ã«æç¤ºãã¹ãããæç¤ºãã¾ããã代ããã«ãèªè¨¼å¨ãå©ç¨å¯è½ãªè³æ ¼æ
å ±ã®ãªã¹ããæä¾ãã¾ããã¦ã¼ã¶ã¼ãè³æ ¼æ
å ±ã鏿ããã¨ãèªè¨¼å¨ã¯ããã«å¯¾å¿ããç§å¯éµã§ãã£ã¬ã³ã¸ã«ç½²åãããã©ã¦ã¶ã¼ã¯ç½²åæ¸ã¿ãã£ã¬ã³ã¸ã¨ãã®credentialIdã RP ãµã¼ãã¼ã«è¿ãã¾ãã
RP ãµã¼ãã¼ã«ããããã®å¾ã®èªè¨¼ããã»ã¹ã¯ãæ¤åºå¯è½ã§ãªãè³æ ¼æ å ±ã®å ´åã¨åæ§ã§ãã
ã¡ã¢:
ç¹å®ã®ã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã§æ¡ä»¶ä»ã仲ä»ãå©ç¨å¯è½ãã©ããã¯ã PublicKeyCredential.isConditionalMediationAvailable() ã¡ã½ãããå¼ã³åºããã¨ã§ç¢ºèªã§ãã¾ãã
ãã¹ãã¼ã¯ãæ¤åºå¯è½ãªèªè¨¼æ å ±ã®éè¦ãªä½¿ç¨ä¾ã§ããå®è£ ã®è©³ç´°ã«ã¤ãã¦ã¯ããã¹ã¯ã¼ãã¬ã¹ãã°ã¤ã³ç¨ã®ãã¹ãã¼ã使ããï¼è±èªï¼ããã³ãã©ã¼ã ã®èªåå ¥åã«ãããã¹ãã¼ã§ã®ãã°ã¤ã³ï¼è±èªï¼ãåç §ãã¦ãã ãããæ¤åºå¯è½ãªè³æ ¼æ å ±ã«é¢ããããä¸è¬çãªæ å ±ã«ã¤ãã¦ã¯ãæ¤åºå¯è½ãªè³æ ¼æ å ±ã®è©³ç´°è§£èª¬ï¼è±èªï¼ãåç §ãã¦ãã ããã
æ¡ä»¶ä»ã仲ä»ãèªè¨¼ã«ä½¿ç¨ãããå ´åããµã¤ã¬ã³ãã¢ã¯ã»ã¹é²æ¢ãã©ã°ï¼CredentialsContainer.preventSilentAccess() åç
§ï¼ã¯å®éã®å¤ã«é¢ããã true 㨠æ±ããã¾ããé©ç¨å¯è½ãªè³æ ¼æ
å ±ãæ¤åºãããå ´åãæ¡ä»¶ä»ãã®åä½ã¯å¸¸ã«ä½ããã®ã¦ã¼ã¶ã¼ä»²ä»ãä¼´ãã¾ãã
ã¡ã¢: è³æ ¼æ å ±ãæ¤åºãããªãã£ãå ´åãéã¢ã¼ãã«ãã¤ã¢ãã°ã¯è¡¨ç¤ºããããã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯è³æ ¼æ å ±ã®ç¨®é¡ã«å¿ãã¦ï¼ä¾ãã°ãè³æ ¼æ å ±ãæã¤æ©å¨ã®æ¿å ¥ãªã©ï¼ãã¦ã¼ã¶ã¼ã«ã¢ã¯ã·ã§ã³ãä¿ããã¨ãã§ãã¾ãã
æ¤åºå¯è½ãªè³æ ¼æ å ±ã®åææ¹æ³
ã¦ã¼ã¶ã¼ã®èªè¨¼å¨ã«æ ¼ç´ããã¦ããæ¤åºå¯è½ãªè³æ ¼æ å ±ã«ã¤ãã¦ã¯ãRP ã®ãµã¼ãã¼ã¨åæããªããªãå¯è½æ§ãããã¾ããããã¯ãã¦ã¼ã¶ã¼ãèªè¨¼å¨ãæ´æ°ããã«ã RP ã¦ã§ãã¢ããªä¸ã§èªè¨¼æ å ±ãåé¤ããããã¦ã¼ã¶ã¼å/表示åã夿´ãããããå ´åã«çããå¯è½æ§ãããã¾ãã
ãã® API ã¯ãRP ãµã¼ãã¼ãèªè¨¼å¨ã«å¤æ´ã®ã·ã°ãã«ãéä¿¡ããæ ¼ç´ãããè³æ ¼æ å ±ãæ´æ°ã§ããããã«ããããã®æ¹æ³ãæä¾ãã¾ãã
PublicKeyCredential.signalAllAcceptedCredentials(): èªè¨¼å¨ã«å¯¾ãã¦ã RP ãµã¼ãã¼ãç¹å®ã®ã¦ã¼ã¶ã¼ã«å¯¾ãã¦ä¿æãã¦ãããã¹ã¦ã®æå¹ãªè³æ ¼æ å ± ID ãã·ã°ãã«ãã¾ããPublicKeyCredential.signalCurrentUserDetails(): ç¹å®ã®ã¦ã¼ã¶ã¼ã RP ãµã¼ãã¼ä¸ã§ã¦ã¼ã¶ã¼åã表示åãæ´æ°ãã¦ãããã¨ããèªè¨¼å¨ã«ã·ã°ãã«ãã¾ããPublicKeyCredential.signalUnknownCredential(): RP ãµã¼ãã¼ãè³æ ¼æ å ± ID ãèªèããªãã£ããã¨ãèªè¨¼å¨ã«ã·ã°ãã«ãã¾ãã
signalUnknownCredential() 㨠signalAllAcceptedCredentials() ã¯ãç®çãä¼¼ã¦ããããã«è¦ããããããã¾ããããããããã©ã®ãããªç¶æ³ã§ä½¿ç¨ãã¹ãã§ããããï¼
signalAllAcceptedCredentials()ã¯ããã°ã¤ã³ã«æåããå¾ãããã³ã¦ã¼ã¶ã¼ããã°ã¤ã³ç¶æ ã§è³æ ¼æ å ±ã®ç¶æ ãæ´æ°ãããå ´åã«å¼ã³åºãå¿ è¦ãããã¾ãããã®ã¡ã½ããã¯ããã®ã¦ã¼ã¶ã¼ã«å¯¾ããcredentialIdã®ãªã¹ãå ¨ä½ãå ±æãããããã¦ã¼ã¶ã¼ãèªè¨¼ããã¦ããå ´åã«ã®ã¿å¼ã³åºãå¿ è¦ãããã¾ããã¦ã¼ã¶ã¼ãèªè¨¼ããã¦ããªãç¶æ ã§å¼ã³åºãã¨ããã©ã¤ãã·ã¼æ¼æ´©ãçºçãã¾ããsignalUnknownCredential()ã¯ããã°ã¤ã³å¤±æå¾ã«å¼ã³åºãã¹ãã§ããããã«ããã鏿ãããèªè¨¼æ å ±ã®credentialIdãæ¤è¨¼ä¸è½ã§ãããé¤å»ãããã¹ãã§ãããã¨ãèªè¨¼å¨ã«ã·ã°ãã«ã¨ãã¦éãã¾ãããã®ã¡ã½ããã¯ãã¦ã¼ã¶ã¼ãèªè¨¼ããã¦ããªãç¶æ ã§ãå®å ¨ã«å¼ã³åºãã¾ãããªããªããèªè¨¼å¨ã«æ¸¡ãã®ã¯åä¸ã®credentialIdï¼ã¯ã©ã¤ã¢ã³ããç´åã«èªè¨¼ã試ã¿ããã®ï¼ã®ã¿ã§ãã¦ã¼ã¶ã¼æ å ±ã¯ä¸åå«ã¾ããªãããã§ãã
ã¯ã©ã¤ã¢ã³ãã®è½åã«åºã¥ããç¬èªã®ã¯ã¼ã¯ããã¼ã®ã«ã¹ã¿ãã¤ãº
ç»é²ã¨ãã°ã¤ã³ã®ã¯ã¼ã¯ããã¼ã¯ãWebAuthn ã¯ã©ã¤ã¢ã³ãï¼ãã©ã¦ã¶ã¼ï¼ã®æ©è½ã«åºã¥ãã¦ãç¬èªã®ã«ã¹ã¿ãã¤ãºãå¯è½ã§ãã PublicKeyCredential.getClientCapabilities() éçã¡ã½ããã使ç¨ãããã¨ãã§ãã¾ãããã®ã¡ã½ããã¯ãªãã¸ã§ã¯ããè¿ããããããã®ãã¼ã¯ WebAuthn ã®æ©è½ã¾ãã¯æ¡å¼µãåç
§ããããããã®å¤ã¯ãã®æ©è½ã«å¯¾å¿ãã¦ãããã©ããã示ãè«çå¤ã§ãã
ããã¯ãä¾ãã°ä»¥ä¸ã®ãã¨ããã§ãã¯ããããã«ä½¿ç¨ãããã¨ãã§ãã¾ãã
- ã¯ã©ã¤ã¢ã³ãã®ãã¹ãã¼ãçä½èªè¨¼ãªã©ã®æ§ã ãªèªè¨¼æ¹å¼ã«ã¤ãã¦ã®å¯¾å¿ç¶æ³ã
- ã¯ã©ã¤ã¢ã³ãã RP ã¨èªè¨¼å¨ã®è³æ ¼æ å ±ãåæãããæ¹æ³ã«å¯¾å¿ãã¦ãããã
- ã¯ã©ã¤ã¢ã³ãããåä¸ãªãªã¸ã³ãæã¤ç°ãªãã¦ã§ããµã¤ãã§åä¸ã®ãã¹ãã¼ã使ç¨ãããã¨ã許å¯ãããã©ããã
以ä¸ã®ã³ã¼ãã¯ãgetClientCapabilities() ã使ç¨ãã¦ãã¯ã©ã¤ã¢ã³ããçä½èªè¨¼ã«ããã¦ã¼ã¶ã¼èªè¨¼ã«å¯¾å¿ãã¦ãããã©ããã確èªããæ¹æ³ã示ãã¦ãã¾ãã
å®éã®åä½ã¯ãµã¤ãã«ãã£ã¦ç°ãªããã¨ã«æ³¨æãã¦ãã ããã
çä½èªè¨¼ãå¿
é ã¨ãããµã¤ãã§ã¯ããã°ã¤ã³ UI ãç½®ãæããçä½èªè¨¼ãå¿
è¦ã§ããæ¨ã¨ãã¦ã¼ã¶ã¼ãå¥ã®ãã©ã¦ã¶ã¼ã端æ«ã試ãããä¿ãã¡ãã»ã¼ã¸ã表示ãããã¨ãã§ãã¾ãã
async function checkIsUserVerifyingPlatformAuthenticatorAvailable() {
const capabilities = await PublicKeyCredential.getClientCapabilities();
// æ©è½ã®ç¢ºèª: userVerifyingPlatformAuthenticator
if (capabilities.userVerifyingPlatformAuthenticator) {
// çä½èªè¨¼ã«å¯¾å¿ãã¦ããå ´åã«è¡ãå¦ç
} else {
// çä½èªè¨¼ã«å¯¾å¿ãã¦ããªãå ´åã«è¡ãå¦ç
}
}
API ã¸ã®ã¢ã¯ã»ã¹å¶å¾¡
WebAuthnã®å©ç¨å¯å¦ã¯ã権éããªã·ã¼ã使ç¨ãã¦å¶å¾¡ã§ãã¾ããç¹ã«ä»¥ä¸ã® 2 ã¤ã®ãã£ã¬ã¯ãã£ããæå®ãã¾ãï¼
publickey-credentials-create:navigator.credentials.create()ã«publicKeyãªãã·ã§ã³ã使ç¨ããå ´åã®å©ç¨å¯å¦ãå¶å¾¡ãã¾ããpublickey-credentials-get:navigator.credentials.get()ã«publicKeyãªãã·ã§ã³ã使ç¨ããå ´åã®å©ç¨å¯å¦ãå¶å¾¡ãã¾ãã
両æ¹ã®ãã£ã¬ã¯ãã£ãã¨ããæ¢å®ã®è¨±å¯ãªã¹ãå¤ã¯ "self" ã§ããããã¯ãæ¢å®ã§ã¯ãããã®ã¡ã½ãããæä¸ä½ã®ææ¸ã³ã³ããã¹ãã§ä½¿ç¨ã§ãããã¨ãæå³ãã¾ãã
ããã«ãget() ã¯æä¸ä½ã®ææ¸ã¨åããªãªã¸ã³ããèªã¿è¾¼ã¾ããããã®ä¸ã«å«ã¾ããé²è¦§ã³ã³ããã¹ãã§ã使ç¨ã§ãã¾ãã
get() ããã³ create() ã¯ãæä¸ä½ã®ææ¸ã¨ã¯ç°ãªããªãªã¸ã³ããèªã¿è¾¼ã¾ãããå
¥ãåã«ãããé²è¦§ã³ã³ããã¹ãï¼ã¤ã¾ããç°ãªããªãªã¸ã³ã® <iframes> å
ï¼ã§ãPermissions-Policy ã® publickey-credentials-get ããã³ publickey-credentials-create ãã£ã¬ã¯ãã£ãã«ãã£ã¦è¨±å¯ããã¦ããå ´åã«éãã¾ãã
ãªãªã¸ã³ãã¾ããã create() å¼ã³åºãã«ããã¦ãiframe ã® allow= ã«ãã£ã¦è¨±å¯ãä¸ããããå ´åããã®ãã¬ã¼ã ã¯ä¸æçãªæå¹åãããã¦ããªããã°ãªãã¾ããã
ã¡ã¢:
ããªã·ã¼ããããã®ã¡ã½ããã®ä½¿ç¨ãç¦æ¢ãã¦ããå ´åãããããè¿ããããã¹ã¯ NotAllowedError ã® DOMException ã§æå¦ããã¾ãã
åºæ¬çãªã¢ã¯ã»ã¹å¶å¾¡
ç¹å®ã®ãµããã¡ã¤ã³ã®ã¿ã¸ã®ã¢ã¯ã»ã¹ã許å¯ãããå ´åã¯ã次ã®ããã«æå®ã§ãã¾ãã
Permissions-Policy: publickey-credentials-get=("https://subdomain.example.com")
Permissions-Policy: publickey-credentials-create=("https://subdomain.example.com")
<iframe> å
ã«åãè¾¼ã¾ãã create ããã³ get() å¼ã³åºãã許å¯
<iframe> å
ã§ get() ã¾ã㯠create() ã«ããèªè¨¼ãè¡ãå ´åã以ä¸ã®æé ã«å¾ã£ã¦ãã ããã
-
RP ãµã¤ããåãè¾¼ããµã¤ãã¯ã
allow屿§ã§è¨±å¯ããå¿ è¦ãããã¾ãã-
get()ã使ç¨ããå ´å:html<iframe src="https://auth.provider.com" allow="publickey-credentials-get *"> </iframe> -
create()ã使ç¨ããå ´å:html<iframe src="https://auth.provider.com" allow="publickey-credentials-create 'self' https://a.auth.provider.com https://b.auth.provider.com"> </iframe>create()ããªãªã¸ã³ãã¾ããã§å¼ã³åºãããå ´åã<iframe>ã«ã¯ä¸æçãªæå¹åãå¿ è¦ã§ãã
-
-
RP ãµã¤ãã¯ã
Permissions-Policyãããã¼ãä»ãã¦ä¸è¨ã®ã¢ã¯ã»ã¹ã«å¯¾ãã¦è¨±å¯ããå¿ è¦ãããã¾ããhttpPermissions-Policy: publickey-credentials-get=* Permissions-Policy: publickey-credentials-create=*ã¾ãã¯ãç¹å®ã® URL ã®ã¿ã
<iframe>å ã§ä¾åå ãµã¤ãã表示ã§ããããã«ãã¾ããhttpPermissions-Policy: publickey-credentials-get=("https://subdomain.example.com") Permissions-Policy: publickey-credentials-create=("https://*.auth.provider.com")
ã¤ã³ã¿ã¼ãã§ã¤ã¹
AuthenticatorAssertionResponse-
ãµã¼ãã¹ã«å¯¾ããèªè¨¼è ã
CredentialsContainer.get()å¼ã³åºãã«ãã£ã¦éå§ãããèªè¨¼è¦æ±ãæ£å¸¸ã«å¦çããããã«å¿ è¦ãªéµãã¢ãä¿æãã¦ãããã¨ã証æãã¾ããget()ã®Promiseãå±¥è¡ãããéã«åå¾ãããPublicKeyCredentialã¤ã³ã¹ã¿ã³ã¹ã®responseããããã£ã§å©ç¨å¯è½ã§ãã AuthenticatorAttestationResponse-
WebAuthn è³æ ¼æ å ±ã®ç»é²çµæï¼ã¤ã¾ãã
CredentialsContainer.create()ã®å¼ã³åºãï¼ãããã«ã¯ããµã¼ãã¼ã WebAuthn ã¢ãµã¼ã·ã§ã³ãå®è¡ããããã«å¿ è¦ãªè³æ ¼æ å ±ã«é¢ããæ å ±ãå«ã¾ãã¾ããä¾ãã°ãè³æ ¼æ å ± ID ãå ¬ééµãªã©ã§ããcreate()ã®Promiseãå±¥è¡ãããéã«åå¾ãããPublicKeyCredentialã¤ã³ã¹ã¿ã³ã¹ã®responseããããã£ã§å©ç¨å¯è½ã§ãã AuthenticatorResponse-
AuthenticatorAttestationResponseããã³AuthenticatorAssertionResponseã®åºæ¬ã¤ã³ã¿ã¼ãã§ã¤ã¹ã§ãã PublicKeyCredential-
å ¬ééµ / ç§å¯éµãã¢ã«é¢ããæ å ±ãæä¾ãã¾ããããã¯ããã¹ã¯ã¼ãã®ä»£ããã«ãã£ãã·ã³ã°æ»æããã¼ã¿ä¾µå®³ã«èæ§ã®ããé対称éµãã¢ã使ç¨ãã¦ãµã¼ãã¹ã«ãã°ã¤ã³ããããã®èªè¨¼æ å ±ã§ãã
Promiseãcreate()ã¾ãã¯get()ã®å¼ã³åºããéãã¦è¿ãã解決ãããã¨ãã«åå¾ããã¾ãã
ä»ã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã¸ã®æ¡å¼µ
CredentialsContainer.create()ã®publicKeyãªãã·ã§ã³-
create()ãpublicKeyãªãã·ã§ã³ä»ãã§å¼ã³åºãã¨ãåè¿°ã®ããã«èªè¨¼å¨ãä»ãã¦æ°ããé対称éµè³æ ¼æ å ±ã®ä½æãéå§ããã¾ãã CredentialsContainer.get()ã®publicKeyãªãã·ã§ã³-
get()ãpublicKeyãªãã·ã§ã³ä»ãã§å¼ã³åºãã¨ãã¦ã¼ã¶ã¼ã¨ã¼ã¸ã§ã³ãã¯æ¢åã®è³æ ¼æ å ±ã»ããã使ç¨ãã¦ä¿¡é ¼å ã¸ã®èªè¨¼ãå®è¡ããããæç¤ºããã¾ãã
ä¾
>ãã¢ãµã¤ã
- Mozilla ãã¢ã¦ã§ããµã¤ãã¨ãã®ã½ã¼ã¹ã³ã¼ãã
- Google ãã¢ã¦ã§ããµã¤ãã¨ãã®ã½ã¼ã¹ã³ã¼ãã
- WebAuthn.io ãã¢ã¦ã§ããµã¤ãã¨ãã®ã½ã¼ã¹ã³ã¼ãã
- github.com/webauthn-open-source ã¨ãã®ã¯ã©ã¤ã¢ã³ãã½ã¼ã¹ã³ã¼ãã¨ãµã¼ãã¼ã½ã¼ã¹ã³ã¼ã
ä½¿ç¨æ³ã®ä¾
ã¡ã¢:
ã»ãã¥ãªãã£ã®è¦³ç¹ãããã¦ã§ãèªè¨¼ã®å¼ã³åºãï¼create() ã get()ï¼ãä¿çããã¦ããéã«ãã©ã¦ã¶ã¼ã¦ã£ã³ãã¦ã®ãã©ã¼ã«ã¹ã失ãããã¨ãå¼ã³åºãã¯ãã£ã³ã»ã«ããã¾ãã
// ç»é²ã®ãµã³ãã«å¼æ°
const createCredentialDefaultArgs = {
publicKey: {
// èªè¨¼ä¾é ¼è
ï¼å¥åãRPããµã¼ãã¹ï¼:
rp: {
name: "Acme",
},
// User:
user: {
id: new Uint8Array(16),
name: "carina.p.anand@example.com",
displayName: "Carina P. Anand",
},
pubKeyCredParams: [
{
type: "public-key",
alg: -7,
},
],
attestation: "direct",
timeout: 60000,
challenge: new Uint8Array([
// ãµã¼ãã¼ããæå·å¦çã«ã©ã³ãã ãªå¤ãéããã¦ããªããã°ãªããªã
0x8c, 0x0a, 0x26, 0xff, 0x22, 0x91, 0xc1, 0xe9, 0xb9, 0x4e, 0x2e, 0x17,
0x1a, 0x98, 0x6a, 0x73, 0x71, 0x9d, 0x43, 0x48, 0xd5, 0xa7, 0x6a, 0x15,
0x7e, 0x38, 0x94, 0x52, 0x77, 0x97, 0x0f, 0xef,
]).buffer,
},
};
// ãã°ã¤ã³ã®ãµã³ãã«å¼æ°
const getCredentialDefaultArgs = {
publicKey: {
timeout: 60000,
// allowCredentials: [newCredential] // ä¸è¨åç
§
challenge: new Uint8Array([
// ãµã¼ãã¼ããæå·å¦çã«ã©ã³ãã ãªå¤ãéããã¦ããªããã°ãªããªã
0x79, 0x50, 0x68, 0x71, 0xda, 0xee, 0xee, 0xb9, 0x94, 0xc3, 0xc2, 0x15,
0x67, 0x65, 0x26, 0x22, 0xe3, 0xf3, 0xab, 0x3b, 0x78, 0x2e, 0xd5, 0x6f,
0x81, 0x26, 0xe2, 0xa6, 0x01, 0x7d, 0x74, 0x50,
]).buffer,
},
};
// æ°ããèªè¨¼æ
å ±ã®ä½æ/ç»é²
navigator.credentials
.create(createCredentialDefaultArgs)
.then((cred) => {
console.log("NEW CREDENTIAL", cred);
// é常ã¯ãµã¼ãã¼ããå©ç¨å¯è½ãªã¢ã«ã¦ã³ãã®èªè¨¼æ
å ±ãéããã¦ãã¾ãã
// ãã®ä¾ã§ã¯ä¸ããã³ãã¼ããã ãã§ãã
const idList = [
{
id: cred.rawId,
transports: ["usb", "nfc", "ble"],
type: "public-key",
},
];
getCredentialDefaultArgs.publicKey.allowCredentials = idList;
return navigator.credentials.get(getCredentialDefaultArgs);
})
.then((assertion) => {
console.log("ASSERTION", assertion);
})
.catch((err) => {
console.log("ERROR", err);
});
仿§æ¸
| 仿§æ¸ |
|---|
| Web Authentication: An API for accessing Public Key Credentials - Level 3 > # iface-pkcredential > |