1. 소개
이 섹션은 규범적이지 않습니다.
웹이 발전함에 따라 개인정보 보호 중심의 변화가 지속적으로 이루어지고 있습니다 (예: Safari, Firefox, Chrome) 및 기본적인 개인정보 보호 원칙의 변화도 이루어지고 있습니다 (예: Privacy Model).
이러한 발전과 함께 웹 플랫폼의 근본적인 가정들이 재정의되거나 제거되고 있습니다. 타사 컨텍스트에서 쿠키에 접근하는 것은 이런 가정 중 하나입니다. 전체적으로 웹에는 긍정적이지만, 타사 쿠키의 폐지는 페더레이티드 아이덴티티의 일부 설계에서 사용되는 근본적인 구성 요소를 없앱니다.
페더레이티드 자격 증명 관리 API는 타사 쿠키에 의존하는 페더레이티드 아이덴티티 설계의 간극을 메우는 것을 목표로 합니다. 이 API는 타사 쿠키에 의존하는 페더레이티드 아이덴티티를 지원하기 위해 필요한 프리미티브들을 제공합니다. (로그인부터 로그아웃 및 폐기까지)
타사 쿠키를 사용하지 않고 페더레이티드 아이덴티티 프리미티브를 제공하기 위해, 이 API는 사용자 에이전트를 RP (페더레이티드 로그인을 위해 사용자 정보를 요청하는 웹사이트)와 IDP (페더레이티드 로그인을 위해 사용자 정보를 제공하는 웹사이트) 사이의 중개자로 둡니다. 이 중개 과정에서는 RP와 IDP가 사용자의 연결을 알기 전에 사용자 허가가 필요합니다.
이 명세는 사용자 에이전트와 IDP의 변화에 크게 의존하며, RP의 변화는 최소화합니다. FedCM API는 인증 및 토큰 획득 방법을 제공합니다.
< html > < head > < title > 내 웹사이트에 오신 것을 환영합니다</ title > </ head > < body > < button onclick = "login()" > idp.example로 로그인</ button > < script > let nonce; async function login() { try { // 임의의 숫자를 반환하는 메서드가 있다고 가정합니다. 이 값을 변수에 저장하여 나중에 토큰에서 반환된 값과 비교할 수 있습니다. nonce= random(); // 사용자가 RP 내에서 페더레이티드 로그인을 위해 사용할 계정을 IDP에서 선택하도록 프롬프트합니다. // 성공적으로 해결되면 Promise는 IdentityCredential 객체를 반환하며, 여기서 |token|을 추출할 수 있습니다. // 이는 IDP에서 RP로 전달되는 불투명한 문자열입니다. let token= await navigator. credentials. get({ identity: { providers: [{ configURL: "https://idp.example/manifest.json" , clientId: "123" , nonce: nonce, }] } }); } catch ( e) { // FedCM 호출이 성공하지 않았습니다. } } </ script > </ body > </ html >
높은 수준에서 페더레이티드 자격 증명 관리 API는 협력하는 IDP와 RP의 중개에 의해 동작합니다.
§ 3 아이덴티티 제공자 HTTP API는 IDP가 노출하는 HTTP API 집합과 § 2 브라우저 API의 진입점을 정의합니다.
사용자 에이전트는 API가 추적 목적으로 사용되는 것을 어렵게 하면서 페더레이티드 아이덴티티 기능을 보존하도록 중개합니다.
2. 브라우저 API
브라우저 API는 RP와 IDP가 호출할 수 있도록 API를 노출하며, 사용자의 아이덴티티 교환을 중개합니다.
회원가입/로그인 API는 RP가 브라우저에 IDP와의 관계 중개 및 토큰 발급을 요청하는 데 사용됩니다.
참고: RP는 회원가입과 로그인을 구분하지 않고 동일한 API를 호출합니다.
모든 과정이 정상적으로 진행되면, Relying Party는 사용자를 인증하는 데 사용할 수 있는 토큰이 포함된 IdentityCredential
을
받습니다.
const credential= await navigator. credentials. get({ identity: { providers: [{ configURL: "https://idp.example/manifest.json" , clientId: "123" , }] } });
쿠키가 포함된 fetch에서는 리소스가 동일-출처 요청으로 로드된 것처럼 파티션되지 않은 쿠키가 포함됩니다. 즉, SameSite 값과 관계없이 (해당 값은 리소스가 타사로 로드될 때 사용됨) 적용됩니다. 이로 인해 IDP가 FedCM API를 쉽게 도입할 수 있습니다. RP는 fetch 결과를 어떠한 방법으로도 검사할 수 없기 때문에 API의 보안에는 영향이 없습니다.
2.1. 로그인 상태 API
2.1.1. 로그인 상태 맵
각 사용자
에이전트는 전역적이며 영구적인 로그인 상태
맵을 유지합니다. 이는 처음에는 비어 있는 맵입니다. 이 맵의 키는 origin(IDP의
origin)이고, 값은 다음 중 하나인 열거형입니다:
"unknown
", "logged-in
",
그리고 "logged-out
".
-
value가 logged-in 또는 logged-out 중 하나임을 단언한다.
2.1.2. 인프라 알고리즘
true
를
반환하면 선조와 동일-사이트입니다:
-
settings의 관련 전역 객체에 연관된 Document가 없다면,
false
를 반환한다. -
document를 settings의 관련 전역 객체의 연관된 Document로 설정한다.
-
document에 탐색 컨텍스트가 없다면
false
를 반환한다. -
origin을 settings의 origin으로 설정한다.
-
navigable을 document의 노드 탐색 가능 객체로 설정한다.
-
navigable에 null이 아닌 parent가 있는 동안:
-
true
를 반환한다.
2.1.3. HTTP 헤더 API
IDP는 아래와 같이 HTTP response header를 통해 로그인 상태를 설정할 수 있습니다.
HTTP 헤더 체크는 Fetch 명세로 옮겨야 합니다. 리소스 로드 전체에 영향을 주기 때문입니다.
각 http-redirect fetch 및 http
fetch의 response에 대해, value를 response의 헤더 리스트에서
이름 "Set-Login
"이고 타입이 "item
"인 구조화 필드 값 가져오기의 결과로 설정한다. value가
null이 아니면, 아래와 같이 처리한다:
-
request의 destination이
"document"
가 아닌 경우:-
client가 null이면 리턴한다.
-
client가 선조와 동일-사이트가 아니면 리턴한다.
-
-
value가 튜플임을 단언한다.
-
token을 value의 첫 번째 값으로 설정한다.
-
token이
"logged-in"
이면, 로그인 상태 설정 알고리즘을 통해 origin에 logged-in을 설정한다. -
token이
"logged-out"
이면, 로그인 상태 설정 알고리즘을 통해 origin에 logged-out을 설정한다.
2.1.4. 자바스크립트 API
IDP는 자바스크립트 API를 사용하여 저장된 로그인 상태를 업데이트할 수도 있습니다:
enum {
LoginStatus ,
"logged-in" , }; [
"logged-out" Exposed =Window ,SecureContext ]interface {
NavigatorLogin Promise <undefined >(
setStatus LoginStatus ); };
status partial interface Navigator { [SecureContext ]readonly attribute NavigatorLogin ; };
login
setStatus()
가 status 인자를 받아 호출될 때:
-
현재 설정 객체가 상위와 동일 사이트가 아니면,
SecurityError
DOMException
을 throw 한다. -
status가
"logged-in"
이면 logged-in을,"logged-out"
이면 logged-out을 value로 설정한다. -
로그인 상태 설정 알고리즘으로 origin에 value를 설정한다.
2.1.5. 로그인 상태 맵 데이터 지우기
User agent는 다음의 경우 로그인 상태 맵 데이터를 반드시 지워야 합니다:
- 사용자가 모든 쿠키 또는 사이트 설정 데이터를 지울 때
-
사용자 에이전트는 전체 맵을 지워야 합니다.
- 사용자가 특정 origin에 대한 모든 쿠키 또는 모든 사이트 데이터를 지울 때
-
사용자 에이전트는 삭제된 쿠키가 전송될 수 있는 origin에 해당하는 모든 엔트리를 제거해야 합니다.
참고: 예를 들어, 도메인 쿠키는 삭제된 origin의 하위 도메인에도 영향을 미칠 수 있습니다.
google.com
의 쿠키를 지울 때accounts.google.com
의 로그인 상태도 초기화해야 합니다. google.com의 도메인 쿠키에 의존할 수 있기 때문입니다. - 사용자가 개별 쿠키를 삭제할 때 (사용자 에이전트가 허용하는 경우)
-
동작은 사용자 에이전트에서 정의합니다.
참고: 사용자 에이전트는 상태를 unknown으로 초기화할 수 있습니다. 해당 쿠키가 인증 상태에 영향을 주는지 판별할 수 없기 때문입니다.
- 사용자 에이전트가 Clear-Site-Data 헤더를
"cookies"
또는"*"
값과 함께 받고, request의 client가 null이 아니며, client의 origin이 동일 origin이고 최상위 origin일 때 -
origin의 쿠키를 지우는 동안 로그인 상태 맵에서 입력 origin을 key로 하는 모든 엔트리를 제거해야 합니다.
Clear-Site-Data 파티션 쿠키 지원 시 문구 업데이트 필요.
참고: 웹사이트가 쿠키를 변경해도 이 맵에는 영향을 주지 않아야 합니다. IDP 로그인 상태가 변경되면 반드시 Set-Login 헤더를 명시적으로 보내야 합니다. RP의 상태는 이 맵에 영향을 주지 않으며, 맵은 IDP 상태만 반영합니다.
2.2. 연결된 계정 집합
각 사용자 에이전트는 전역 연결된 계정 집합을 가지고 있으며, 처음에는 비어 있는 순서가 있는 집합입니다. 항목은 (rp, idp, account) 형태의 트리플이며, rp는 RP의 origin, idp는 IDP의 origin, account는 계정 식별자를 나타내는 문자열입니다. 사용자가 FedCM으로 해당 rp에 idp account로 로그인한 트리플 집합을 나타냅니다.
연결된 계정 집합은 RP에서 이중 키로 관리되어야 합니다 (즉, 요청자와 임베더 모두, iframe과 최상위가 모두 포함). 그렇지 않으면 최상위 상태가 임베더에 의해 사용/수정될 수 있어 정보 유출 및 원치 않는 크로스 오리진 통신이 발생할 수 있습니다.
사용자가 origin에 대한 브라우징 데이터를 지우면(쿠키, localStorage 등), 사용자 에이전트는 연결된 계정 집합에서 origin과 일치하는 origin의 모든 트리플을 제거해야 합니다.
IdentityProviderConfig
provider, IdentityProviderAccount
account, globalObject가 주어지면 다음 절차를 실행하여 (rp, idp, account) 형태의 트리플을 반환합니다.
-
configUrl을 parse url 알고리즘으로 provider의
configURL
및 globalObject를 사용해 계산한다. -
idpOrigin을 configUrl에 해당하는 origin으로 설정한다.
-
rpOrigin을 globalObject의 연결된 Document의 origin으로 설정한다.
-
accountId를 account의
id
로 설정한다. -
(rpOrigin, idpOrigin, accountId)를 반환한다.
IdentityProviderAccount
account이 자동 재인증 대상인지 확인하려면, IdentityProviderConfig
provider, globalObject를 받아 다음 절차를 실행한다. 반환값은 boolean.
-
account가
approved_clients
를 가지고 있고, account의approved_clients
가 provider의clientId
를 포함하지 않으면, false를 반환한다. -
triple을 연결된 계정 키 계산 알고리즘으로 provider, account, globalObject로 계산한다.
-
연결된 계정 집합이 triple을 포함하는지 반환한다.
IdentityProviderAccount
account, IdentityProviderConfig
provider, globalObject가 주어지면 다음 절차를 실행한다.
반환값은 connected 또는 disconnected이다.
-
account가
approved_clients
를 가지고 있다면:-
만약 account의
approved_clients
에 provider의clientId
가 포함되어 있다면, connected를 반환한다. -
disconnected를 반환한다.
-
-
triple을 연결된 계정 키 계산 알고리즘으로 provider, account, globalObject로 계산한다.
-
연결된 계정 집합이 triple을 포함하면, connected를 반환한다.
-
disconnected를 반환한다.
IdentityProviderConfig
provider, IdentityProviderAccount
account, globalObject(RP의)을
받아 다음 절차를 실행한다:
-
configUrl을 parse url 알고리즘으로 provider의
configURL
및 globalObject를 사용해 계산한다. -
idpOrigin을 configUrl에 해당하는 origin으로 설정한다.
-
rpOrigin을 globalObject의 연결된 Document의 origin으로 설정한다.
-
accountId를 account의
id
로 설정한다. -
triple을 (rpOrigin, idpOrigin, accountId)로 설정한다.
-
연결된 계정 집합에 triple을 추가한다.
-
triple을 (rpOrigin, idpOrigin, accountId)로 설정한다.
-
-
연결된 계정 집합에서 triple을 제거한다.
-
true를 반환한다.
-
-
false를 반환한다.
-
모든 (rp, idp, accountId) triple에 대해 연결된 계정 집합에서:
-
rp가 rpOrigin과 같고 idp가 idpOrigin과 같으면 triple을 연결된 계정 집합에서 제거한다.
-
2.3. IdentityCredential 인터페이스
이 명세에서는 Credential
의
새로운 종류인 IdentityCredential
을
도입합니다:
dictionary :
IdentityCredentialDisconnectOptions IdentityProviderConfig {required USVString ; }; [
accountHint Exposed =Window ,SecureContext ]interface :
IdentityCredential Credential {static Promise <undefined >(
disconnect optional IdentityCredentialDisconnectOptions = {});
options readonly attribute USVString ?;
token readonly attribute boolean ; };
isAutoSelected
id
-
id
의 attribute getter는 빈 문자열을 반환합니다. token
-
token
의 attribute getter는 설정된 값을 반환합니다. IDP에서 제공하는token
을 나타냅니다. isAutoSelected
-
isAutoSelected
의 attribute getter는 설정된 값을 반환합니다. UI 흐름에서 사용자의 아이덴티티 자격 증명이 자동 선택되었는지 나타냅니다. 이로 인해IdentityCredential
이 생성됩니다. [[type]]
-
IdentityCredential
의[[type]]
값은 "identity"입니다. [[discovery]]
-
IdentityCredential
의[[discovery]]
값은remote
입니다.
이 명세의 주요 진입점은 Credential Management API에서 노출되는 엔트리포인트를 통해 접근합니다.
2.3.1. disconnect 메서드
disconnect
메서드가 IdentityCredentialDisconnectOptions
options와 함께 호출되면, 다음 단계를 수행한다:
-
globalObject를 현재 전역 객체로 설정한다.
-
document를 globalObject의 연관된 Document로 설정한다.
-
document가 identity-credentials-get 정책 제어 기능을 사용할 수 없으면, "
NotAllowedError
"DOMException
을 throw 한다. -
promise를 새
Promise
로 설정한다. -
promise를 반환한다.
IdentityCredentialDisconnectOptions
options, Promise
promise, globalObject가 주어지면 다음 단계를 수행한다:
-
단언: 이 단계는 병렬로 실행됨.
-
configUrl을 parse url 알고리즘으로 options의
configURL
및 globalObject로 계산한다. -
configUrl이 failure이면 promise를 "
InvalidStateError
"DOMException
으로 reject 한다. -
Content Security Policy Level 3의 connect-src 지시어로 configUrl에 대해 체크한다. 실패하면 promise를 "
NetworkError
"DOMException
으로 reject 한다. -
해당 globalObject에 대해 pending
disconnect
호출이 있으면(예: 아직 예외가 throw되지 않았거나 관련Promise
가 resolve되지 않았으면), promise를 "NetworkError
"DOMException
으로 reject 한다. -
configUrl이 신뢰할 수 있는 origin이 아니면 promise를 "
NetworkError
"DOMException
으로 reject 한다. -
사용자가 globalObject에서 FedCM API를 비활성화했다면 promise를 "
NetworkError
"DOMException
으로 reject 한다. -
connected accounts set에 다음과 같이 연결된 계정 키 계산 알고리즘으로 account, options, globalObject의 결과가 포함된 account가 없으면 promise를 "
NetworkError
"DOMException
으로 reject 한다. 이 체크는 connected accounts set을 순회하거나 별도의 자료구조를 유지해 빠르게 조회할 수 있다. -
config를 fetch the config file 알고리즘으로 provider, globalObject로 계산한다.
-
config이 failure이면 promise를 "
NetworkError
"DOMException
으로 reject 한다. -
disconnectUrl을 computing the manifest URL 알고리즘으로 provider, config.
disconnect_endpoint
, globalObject로 계산한다. -
disconnectUrl이 failure이면 promise를 "
NetworkError
"DOMException
으로 reject 한다. -
연결 해제 요청 보내기 알고리즘을 disconnectUrl, options, globalObject로 실행하고, 결과를 result로 설정한다.
-
idpOrigin을 configUrl에 해당하는 origin으로 설정한다.
-
rpOrigin을 globalObject의 연결된 Document의 origin으로 설정한다.
-
result가 failure이면:
-
모든 연결 삭제 알고리즘을 rpOrigin, idpOrigin으로 실행한다.
-
promise를 "
NetworkError
"DOMException
으로 reject 한다. -
return.
-
-
accountId를 result로 설정한다 (failure가 아님).
-
연결 삭제 알고리즘을 accountId, rpOrigin, idpOrigin으로 실행하고, 결과를 wasAccountRemoved로 설정한다.
-
wasAccountRemoved가 false면, 모든 연결 삭제 알고리즘을 rpOrigin, idpOrigin으로 실행한다.
-
promise를 resolve 한다.
2.3.1.1. 연결 해제 요청
연결 해제 요청 보내기 알고리즘은 RP에서 페더레이티드 로그인에 사용된 계정의 연결을 해제하기 위한 요청을 보낸다.
IdentityCredentialDisconnectOptions
options, globalObject가 주어지면 다음 단계를 수행한다. 반환값은 USVString
또는 failure.
-
requestBody를 urlencoded serializer 알고리즘으로 다음 리스트로 계산한다:
-
("client_id", options의
clientId
) -
("account_hint", options의
accountHint
)
-
-
request를 다음과 같이 새 request로 설정한다:
- url
-
disconnectUrl
- method
-
"POST"
- body
-
UTF-8 인코딩된 requestBody
- redirect mode
-
"error"
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
-
globalObject의 연결된 document의 origin
- header list
-
리스트로, header 하나만 있고, name은
Accept
, value는application/x-www-form-urlencoded
- credentials mode
-
"include"
- mode
-
"cors"
-
accountId를 null로 설정한다.
-
fetch request 알고리즘을 request, globalObject와 함께 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행한다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출한다.
-
변환 json을
DisconnectedAccount
타입 account으로 변환한다. -
위 두 단계 중 예외가 발생하면 accountId를 failure로 설정하고 return.
-
accountId를 account의
account_id
로 설정한다.
-
-
accountId가 설정될 때까지 기다린다.
-
accountId를 반환한다.
dictionary {
DisconnectedAccount required USVString account_id ; };
2.3.2. CredentialRequestOptions
이 섹션에서는 자바스크립트 호출에 전달되는 딕셔너리를 정의한다:
const credential= await navigator. credentials. get({ identity: { // IdentityCredentialRequestOptions providers: [{ // sequence<IdentityCredentialRequestOptions> configURL: "https://idp.example/manifest.json" , // IdentityProviderConfig.configURL clientId: "123" , // IdentityProviderConfig.clientId nonce: "nonce" // IdentityProviderConfig.nonce }] } });
이 명세에서는 CredentialRequestOptions
객체에 대한 확장을 도입한다:
partial dictionary CredentialRequestOptions {IdentityCredentialRequestOptions ; };
identity
IdentityCredentialRequestOptions
는 RP가 지원하고 사전 등록한 IdentityProviderConfig
리스트를 포함한다 (즉, IDP가 RP에 clientId
를 제공함).
IdentityCredentialRequestOptions
는 또한 IdentityCredentialRequestOptionsContext
를
포함하며, 사용자 에이전트가 더 의미 있는 다이얼로그를 제공할 수 있게 한다.
enum {
IdentityCredentialRequestOptionsContext ,
"signin" ,
"signup" ,
"use" };
"continue" dictionary {
IdentityCredentialRequestOptions required sequence <IdentityProviderRequestOptions >;
providers IdentityCredentialRequestOptionsContext = "signin"; };
context
각 IdentityProviderConfig
는 IDP를 나타내며,
RP가 지원하는 대상이다 (예: 사전 등록 협약이 있음).
dictionary {
IdentityProviderConfig required USVString ;
configURL required USVString ; };
clientId dictionary :
IdentityProviderRequestOptions IdentityProviderConfig {USVString ;
nonce DOMString ;
loginHint DOMString ; };
domainHint
configURL
-
아이덴티티 제공자의 설정 파일 URL입니다.
clientId
nonce
-
RP가 선택한 임의의 숫자입니다. 일반적으로 클라이언트 세션을
token
과 연관시키고 재실행 공격을 완화하기 위해 사용됩니다. 따라서 충분한 엔트로피를 가져야 하며, 쉽게 추측할 수 없어야 합니다. loginHint
-
RP가 사용자 에이전트에게 사용자에게 보여주길 원하는 계정에 대응하는 로그인 힌트를 나타내는 문자열입니다. 제공된 경우, 사용자 에이전트는 이 로그인 힌트 값과 일치하지 않는 계정은 표시하지 않습니다. 일반적으로 원하는
IdentityProviderAccount
의 속성과 일치합니다. domainHint
-
RP가 관심 있는 도메인에 대응하는 도메인 힌트를 나타내는 문자열입니다. RP가 모든 도메인 힌트와 연결된 계정을 원할 경우 "any"를 사용합니다. 제공된 경우, 사용자 에이전트는 이 도메인 힌트 값과 일치하지 않는 계정은 표시하지 않습니다.
2.3.3.
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
내부 메서드
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
알고리즘은 Credential Management
1 § 2.5.1 자격 증명 요청 내부에서 병렬로 실행되어
자격 증명을 요청하고 IdentityCredential
또는 오류를 반환합니다.
이 내부 메서드는 세 가지 인자를 받습니다:
origin
-
이 인자는 관련 설정 객체의 origin이며, 호출하는
get()
구현에 따라 결정됩니다. 즉,CredentialsContainer
의 자격 증명 요청 추상 연산입니다. options
-
이 인자는
CredentialRequestOptions
객체이며, 그identity
멤버가 존재합니다. sameOriginWithAncestors
-
이 인자는 Boolean 값으로, caller의 환경 설정 객체가 상위와 동일 오리진이면
true
이고, 교차 오리진인 경우false
입니다.참고: 이 내부 메서드의 호출은 권한정책에 의해 허용됨을 나타내며, 이는 Credential Management Level 1 수준에서 평가됩니다. § 4 권한 정책 통합 참고. 따라서 sameOriginWithAncestors는 사용되지 않습니다.
options.signal
은 요청의 abort signal로 사용됩니다.
IdentityCredential
의
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
알고리즘이 호출되면, 사용자 에이전트는 반드시 다음 단계를 실행해야 합니다. 이 알고리즘은 IdentityCredential
(또는 호출자에게 오류를 throw)로 반환합니다.
-
단언: 이 단계는 병렬로 실행됩니다.
-
options["
identity
"]["providers
"] 의 크기가 1이 아니면, 글로벌 태스크 큐에 DOM 조작 태스크 소스를 사용해 globalObject에서 새로운 "NetworkError
"DOMException
을 throw한다.참고: globalObject는 현재
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
알고리즘에 전달되지 않습니다. 이슈 참고. -
사용자 에이전트는 다음 단계로 진행할 시점을 임의로 결정할 수 있습니다.
참고: 예를 들어, 사용자 에이전트는 네트워크 요청 전에 아이덴티티 제공자 선택기를 보여주거나, URL 바에 버튼을 제공하고 사용자 입력을 기다릴 수 있습니다.
-
credential을 IdentityCredential 생성 알고리즘으로 provider, options, globalObject를 사용하여 실행합니다.
-
credential이 쌍(pair)이면:
-
throwImmediately를 쌍의 두 번째 요소 값으로 설정합니다.
-
다음 조건이 모두 충족되면, 사용자 에이전트는 다음 단계까지 임의의 시간 지연을 두어야 합니다:
-
throwImmediately가 false임
-
promise reject 지연이 사용자 에이전트 자동화로 비활성화되지 않았음
-
사용자 에이전트가 RP에게 사용자가 RP에 로그인된 계정이 있는지 노출하는 다른 방법을 구현하지 않았음
참고: 여기서의 의도는 다음과 같습니다. 만약 promise가 즉시 해결되면, RP는 네트워크 지연 이후 빠르게 promise가 해결되어 다이얼로그가 나타나지 않았음을 추론할 수 있습니다. 다이얼로그가 나타나면 사용자가 IDP 계정에 하나 이상 로그인되어 있음을 의미합니다. 이 정보 유출을 막기 위해, 특히 사용자 확인 없이, 이 지연이 명시됩니다. 단, UA는 다른 UI 접근법으로 막을 수 있습니다.
-
-
글로벌 태스크 큐에 DOM 조작 태스크 소스를 사용해 새로운 "
NetworkError
"DOMException
을 throw한다.
-
-
그 외에는 credential을 반환합니다.
2.3.4. IdentityCredential 생성
IdentityCredential 생성 알고리즘은 여러 FedCM fetch, 사용자 에이전트 UI
제공, IdentityCredential
생성을 실행하며, 결과는 RP에 반환됩니다.
IdentityProviderRequestOptions
provider, CredentialRequestOptions
options, globalObject가 주어지면 다음을 실행한다. 반환값은 IdentityCredential
또는 (failure, bool) 쌍이며, bool은 예외 throw 지연을 건너뛸지 여부를 나타낸다.
-
단언: 이 단계는 병렬로 실행된다.
-
loginStatus를 로그인 상태 가져오기 알고리즘으로 provider의
configURL
의 origin을 사용해 계산한다. -
loginStatus가 unknown이면, 사용자 에이전트는 이를 logged-out으로 설정할 수 있다.
-
loginStatus가 logged-out이면, 사용자 에이전트는 다음 중 하나를 반드시 수행한다:
-
(failure, false) 반환
-
사용자에게 계속 진행할지 프롬프트. 사용자가 계속하면 loginStatus를 unknown으로 설정해야 함. 이 과정은 IDP 로그인 다이얼로그 표시를 포함할 수 있음.
-
사용자가 다이얼로그를 취소하면 (failure, true) 반환
-
사용자가 해당 affordance를 트리거하면:
-
config를 설정 파일 가져오기 알고리즘으로 provider, globalObject로 계산
-
config가 failure면 (failure, true) 반환
-
IDP 로그인 다이얼로그 표시 알고리즘을 config, provider로 실행
-
해당 알고리즘이 failure를 반환하면 (failure, true) 반환. 사용자 에이전트는 실패를 반환하기 전/후에 사용자에게 실패 다이얼로그를 보여줄 수 있음.
-
-
RP가 두 번째 옵션(사용자 affordance 제공)을 요청할 수 있는 방법을 제공해야 함. 관련 논의 참고.
-
-
requiresUserMediation을 provider의
configURL
의 origin의 사용자 조정 필요 여부로 설정 -
mediation을 options의
mediation
으로 설정 -
requiresUserMediation이 true이고 mediation이 "
silent
" 이면 (failure, true) 반환 -
config를 설정 파일 가져오기 알고리즘으로 provider, globalObject로 계산
-
config가 failure면 (failure, false) 반환
-
계정 가져오기 단계: accountsList를 계정 가져오기 알고리즘으로 config, provider, globalObject로 계산
-
accountsList가 failure이거나 크기가 0이면:
-
로그인 상태 설정 알고리즘으로
configURL
의 origin에 logged-out을 설정. 자격 증명이 서버에 전송되지 않은 경우, 사용자 에이전트는 이 단계를 생략할 수 있음.참고: 예를 들어, fetch가 DNS 오류로 실패하면 자격 증명이 전송되지 않아 IDP가 사용자의 신원을 알 수 없습니다. 이 상황에서는 사용자가 로그인 상태인지 알 수 없으므로 상태를 초기화하지 않을 수 있습니다.
-
불일치 다이얼로그 단계: loginStatus가 logged-in이면, 사용자에게 다이얼로그를 표시합니다. 다이얼로그 내용은 사용자 에이전트가 정의합니다. 이 다이얼로그는 사용자가 IDP 로그인 다이얼로그 표시 알고리즘을 config, provider로 트리거할 수 있도록 affordance를 제공해야 하며, 이 다이얼로그를 IDP 로그인 확인 다이얼로그라 한다.
참고: 이 상황은 브라우저가 사용자가 로그인되어 있을 것으로 예상하지만, 계정 fetch 결과 사용자가 로그아웃되어 있음을 나타낼 때 발생합니다.
참고: 이 다이얼로그는 자격 증명이 서버로 전송된 경우 항상 UI를 표시해 사용자 추적이 조용히 이루어질 수 없도록 보장합니다.
-
다음 중 하나가 발생할 때까지 기다립니다:
-
사용자가 다이얼로그를 닫으면 (failure, true) 반환
-
IDP 로그인 다이얼로그 표시 알고리즘이 트리거되면:
-
result를 해당 알고리즘의 결과로 설정
-
result가 failure면 (failure, true) 반환. 사용자 에이전트는 실패를 반환하기 전/후에 실패 표시 다이얼로그를 보여줄 수 있음.
-
그 외에는 계정 가져오기 단계로 돌아감.
-
-
-
-
-
단언: accountsList는 failure가 아니고 크기가 0이 아님.
-
provider의
loginHint
값이 비어 있지 않으면:-
accountList의 각 account에 대해, account의
login_hints
에 provider의loginHint
가 포함되지 않으면 account를 accountList에서 제거 -
accountList가 비어 있으면 불일치 다이얼로그 단계로 이동
-
-
provider의
domainHint
값이 비어 있지 않으면:-
accountList의 각 account에 대해:
-
domainHint
가 "any"이면:-
account의
domain_hints
가 비어 있으면 account를 accountList에서 제거
-
-
그 외에는 account의
domain_hints
에 provider의domainHint
가 포함되지 않으면 account를 accountList에서 제거
-
-
accountList가 비어 있으면 불일치 다이얼로그 단계로 이동
-
-
accountsList의 각 acc에 대해:
-
acc["
picture
"] 가 존재하면 계정 사진 가져오기 알고리즘을 acc, globalObject로 실행
참고: 사용자 에이전트는 계정 사진 fetch가 처음에는 필요 없는 UI를 보여줄 수 있습니다. 이런 경우 fetch는 나중에 필요할 때까지 지연될 수 있습니다. fetch 오류는 무시되므로 순서 없이 실행 가능합니다.
-
-
registeredAccount, numRegisteredAccounts를 각각 null, 0으로 설정
-
account를 null로 설정
-
accountsList의 각 acc에 대해:
-
acc가 자동 재인증 대상이면 registeredAccount에 acc를 설정하고 numRegisteredAccounts를 1 증가
-
-
permission, disclosureTextShown, isAutoSelected를 false로 설정
-
mediation이 "
required
"가 아니고, requiresUserMediation이 false이며 numRegisteredAccounts가 1이면:-
account를 registeredAccount로, permission을 true로 설정. 이때 사용자 에이전트는 자동 재인증됨을 알리는 UI를 표시할 수 있음 자동 재인증됨
-
isAutoSelected를 true로 설정
-
-
그 외에 mediation이 "
silent
"이면 (failure, true) 반환 -
그 외에 accountsList의 크기가 1이면:
-
account를 accountsList[0]으로 설정
-
연결 상태 계산 알고리즘으로 account, provider, globalObject의 결과가 connected이면, 사용자에게 해당 계정으로 로그인 허가 요청 다이얼로그를 표시하고 결과를 permission에 설정. 사용자 에이전트는 options의
context
를 사용해 다이얼로그를 커스터마이징할 수 있음 -
그 외에는 permission을 회원가입 허가 요청 알고리즘 결과로 설정하고 disclosureTextShown을 true로 설정
-
-
그 외에는:
-
account를 계정 선택 알고리즘 결과로 설정
-
account가 failure면 (failure, true) 반환
-
연결 상태 계산 알고리즘으로 account, provider, globalObject의 결과가 connected이면 permission을 true로 설정
-
그 외에는:
-
permission을 회원가입 허가 요청 알고리즘 결과로 설정하고 disclosureTextShown을 true로 설정
-
-
-
이전 단계에서 생성된 사용자 선택/허가 다이얼로그가 있다면, 다이얼로그가 닫힐 때까지 기다림
-
단언: account는 null이 아님
-
permission이 false면 (failure, true) 반환
-
credential을 아이덴티티 어설션 fetch 알고리즘으로 account의
id
, disclosureTextShown, isAutoSelected, provider, config, globalObject로 실행 -
credential을 반환
2.3.5. 설정 파일 가져오기
설정 파일 가져오기 알고리즘은 IDP에서 웰노운 파일과 설정 파일을 모두 가져오고, 설정 파일이 웰노운 파일에 명시되어 있는지 확인한 후 config를 반환합니다.
IdentityProviderRequestOptions
provider, globalObject가 주어지면 다음 단계를 수행합니다. 반환값은 IdentityProviderAPIConfig
또는 failure입니다.
-
configUrl을 parse url 알고리즘으로 provider의
configURL
및 globalObject로 계산합니다. -
configUrl이 failure이면, failure를 반환합니다.
-
Content Security Policy Level 3의 connect-src 지시어로 configUrl에 대해 체크합니다. 실패 시 failure를 반환합니다.
-
configUrl이 신뢰할 수 있는 URL이 아니면, failure를 반환합니다.
-
rootUrl을 새 URL로 생성합니다.
-
rootUrl의 host 를 configUrl의 host의 등록 가능한 도메인으로 설정합니다.
-
config, configInWellKnown을 모두 null로 설정합니다.
-
rpOrigin을 globalObject의 연결된 Document의 origin으로 설정합니다.
-
rpOrigin이 불투명 origin이 아니고, rootUrl의 host가 rpOrigin의 등록 가능한 도메인과 같고, rootUrl의 scheme이 rpOrigin의 scheme과 같으면, configInWellKnown을 true로 설정합니다.
참고: 도메인 쿠키가 사이트 전체에서 유효하므로, RP와 IDP가 동일 사이트일 때 웰노운 체크를 하는 것은 개인정보 보호에 도움이 되지 않습니다.
-
그렇지 않으면:
-
wellKnownRequest를 다음과 같이 새 request로 생성합니다:
- URL
-
rootUrl
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
-
고유한 불투명 origin
- header list
- referrer policy
-
"no-referrer"
- credentials mode
-
"omit"
- mode
-
"no-cors"
모든 request가 mode "user-agent-no-cors"로 생성되도록 명세 업데이트 필요. 관련 PR 참고.
-
Fetch request 알고리즘을 wellKnownRequest, globalObject로 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행합니다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출합니다.
-
변환 json을
IdentityProviderWellKnown
타입 discovery로 변환합니다. -
위 두 단계 중 예외가 발생하거나 discovery["
provider_urls
"] 크기가 1보다 크면, configInWellKnown을 false로 설정합니다.provider_urls 배열 크기 제한 완화 필요 참조.
-
그 외에는 discovery["
provider_urls
"][0] 이 provider의configURL
와 같으면 configInWellKnown을 true로, 아니면 false로 설정합니다.
-
-
-
configRequest를 다음과 같이 새 request로 생성합니다:
- url
-
configUrl
- redirect mode
-
"error"
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
-
고유한 불투명 origin
- header list
- referrer policy
-
"no-referrer"
- credentials mode
-
"omit"
- mode
-
"no-cors"
모든 request가 mode "user-agent-no-cors"로 생성되도록 명세 업데이트 필요. 관련 PR 참고.
-
Fetch request 알고리즘을 configRequest, globalObject로 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행합니다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출합니다.
-
변환 json을
IdentityProviderAPIConfig
타입으로 변환하여 config에 저장합니다. -
위 두 단계 중 예외가 발생하면 config를 failure로 설정합니다.
-
config.
login_url
을 manifest URL 계산 알고리즘으로 provider, config, globalObject로 계산한 값으로 설정합니다. -
config.
login_url
이 null이면, failure 반환
-
-
config, configInWellKnown이 모두 설정될 때까지 기다립니다.
-
configInWellKnown이 true면 config 반환, 아니면 failure 반환
참고: 2단계 파일 시스템은 IDP가 config 파일 경로에 RP 정보를 인코딩하여 사용자가 방문한 RP를 쉽게 알아낼 수 없도록 방지하기 위해 사용됩니다. 이런 문제는 웰노운 파일을 IDP의 루트에 위치하도록 요구함으로써 해결됩니다. 설정 파일은 임의 경로에 위치할 수 있지만, 사용자 에이전트가 웰노운 파일에서 찾지 못하면 사용되지 않습니다. 이렇게 하면 IDP가 실제 설정 파일을 임의 경로에 둘 수 있으면서도, 사용자 에이전트가 경로 조작을 통한 지문 채취(예: 경로에 RP 포함)를 막을 수 있습니다. § 7.3.1 Manifest Fingerprinting 참고.
dictionary {
IdentityProviderWellKnown required sequence <USVString >provider_urls ; };dictionary {
IdentityProviderIcon required USVString url ;unsigned long size ; };dictionary {
IdentityProviderBranding USVString background_color ;USVString color ;sequence <IdentityProviderIcon >icons ;USVString name ; };dictionary {
IdentityProviderAPIConfig required USVString accounts_endpoint ;required USVString client_metadata_endpoint ;required USVString id_assertion_endpoint ;required USVString ;
login_url USVString disconnect_endpoint ;IdentityProviderBranding branding ; };
2.3.6. 계정 가져오기
계정 가져오기 알고리즘은 accounts endpoint를 가져와서 사용자가 로그인한 IDP 계정 목록을 확인하여, 이후 사용자 에이전트가 FedCM UI를 사용자에게 보여줄 수 있도록 합니다.
IdentityProviderAPIConfig
config, IdentityProviderRequestOptions
provider, globalObject가 주어지면 다음 단계를 수행합니다. 반환값은 IdentityProviderAccountList
입니다.
-
accountsUrl을 manifest URL 계산 알고리즘으로 provider, config["
accounts_endpoint
"], globalObject로 계산합니다. -
accountsUrl이 failure이면, 빈 리스트를 반환합니다.
-
request를 다음과 같이 새 request로 생성합니다:
- url
-
accountsUrl
- redirect mode
-
"error"
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
-
고유한 불투명 origin
- header list
- referrer policy
-
"no-referrer"
- credentials mode
-
"include"
- mode
-
"no-cors"
이 알고리즘의 credentialed fetch는 사용자가 권한을 허가하기 전에 타이밍 공격으로 사용자의 신원을 유출할 수 있습니다. 관련 논의 참고.
모든 request가 mode "user-agent-no-cors"로 생성되도록 명세 업데이트 필요. 관련 PR 참고.
-
accountsList를 null로 설정합니다.
-
Fetch request 알고리즘을 request, globalObject로 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행합니다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출합니다.
-
변환 json을
IdentityProviderAccountList
타입으로 변환하여 accountsList에 저장합니다. -
위 두 단계 중 예외가 발생하면 accountsList를 failure로 설정합니다.
반환된 계정 리스트는 중복 id 검증이 필요합니다. 관련 설명.
-
-
accountsList가 설정될 때까지 기다립니다.
-
accountsList를 반환합니다.
dictionary {
IdentityProviderAccount required USVString id ;required USVString name ;required USVString USVString given_name ;USVString picture ;sequence <USVString >approved_clients ;sequence <DOMString >login_hints ;sequence <DOMString >domain_hints ; };dictionary {
IdentityProviderAccountList sequence <IdentityProviderAccount >; };
accounts
IdentityProviderAccount
account, globalObject가 주어지면 다음 단계를 수행합니다:
-
pictureUrl을 parse url 알고리즘으로 account["
picture
"] 및 globalObject로 계산합니다. -
pictureUrl이 failure이면, 이 단계를 중단합니다. 사용자 에이전트는 플레이스홀더 이미지를 사용할 수 있습니다.
-
pictureRequest를 다음과 같이 새 request로 생성합니다:
- url
-
pictureUrl
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"image"
- origin
-
고유한 불투명 origin
- referrer policy
-
"no-referrer"
- credentials mode
-
"omit"
- mode
-
"no-cors"
모든 request가 mode "user-agent-no-cors"로 생성되도록 명세 업데이트 필요. 관련 PR 참고.
-
Fetch request 알고리즘을 pictureRequest, globalObject로 실행하고, processResponseConsumeBody는 response, responseBody를 받아 다음 단계로 실행합니다:
-
responseBody가 null 또는 failure이면, 사용자 에이전트는 임의의 플레이스홀더 이미지를 선택해 account에 연결할 수 있습니다.
-
그 외에는 responseBody 이미지를 디코딩해 성공 시 account에 연관시킵니다. 이렇게 하면 사용자 에이전트가 해당 이미지를 계정 다이얼로그에 사용할 수 있습니다.
-
2.3.7. 아이덴티티 어설션 가져오기
아이덴티티 어설션 가져오기 알고리즘은 사용자가 특정 IDP 계정으로 FedCM 사용을 허가한 후 호출됩니다. 이 알고리즘은 아이덴티티 어설션 엔드포인트에서 RP에 제공될 토큰을 가져옵니다.
USVString
accountId, boolean disclosureTextShown, boolean isAutoSelected, IdentityProviderRequestOptions
provider, IdentityProviderAPIConfig
config,
globalObject가 주어지면 다음 단계를 실행합니다. 반환값은 IdentityCredential
또는 실패입니다.
-
tokenUrl을 manifest URL 계산 알고리즘으로 provider, config["
id_assertion_endpoint
"], globalObject로 계산합니다. -
tokenUrl이 실패이면, 실패를 반환합니다.
-
requestBody를 urlencoded serializer 알고리즘으로 다음 리스트로 계산합니다:
-
request를 다음과 같이 새 request로 생성합니다:
- url
-
tokenUrl
- method
-
"POST"
- body
-
UTF-8 인코딩된 requestBody
- redirect mode
-
"error"
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
-
globalObject의 연결된 document의 origin
- header list
-
리스트로, header 하나만 있고, name은
Accept
, value는application/x-www-form-urlencoded
- credentials mode
-
"include"
- mode
-
"cors"
-
credential을 null로 설정합니다.
-
Fetch request 알고리즘을 request, globalObject로 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행합니다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출합니다.
-
변환 json을
IdentityProviderToken
타입 token으로 변환합니다. -
위 두 단계 중 예외가 발생하면 credential을 실패로 설정하고 return.
-
credential을
IdentityCredential
로 새로 만들고, globalObject의 realm을 사용합니다. -
credential의
token
을 token으로 설정합니다. -
credential의
isAutoSelected
을 isAutoSelected으로 설정합니다.
-
-
credential이 설정될 때까지 기다립니다.
-
credential을 반환합니다.
dictionary {
IdentityProviderToken required USVString token ; };
2.3.8. 회원가입 허가 요청
IdentityProviderAccount
또는 실패입니다.
-
accountsList의 크기가 1보다 큼을 단언합니다.
-
accountsList의 옵션을 표시하는 계정 선택기를 표시합니다.
-
사용자가 계정 선택기에서 직접 선택한
IdentityProviderAccount
를 account로, 계정이 선택되지 않으면 실패로 설정합니다. -
account를 반환합니다.
회원가입 허가 요청 알고리즘은 RP의 client metadata endpoint를 가져와서, 사용자가 해당 계정 사용에 대한 명시적 허가를 할 때까지 기다린 후, 허가 여부를 반환합니다.
IdentityProviderAccount
account,
IdentityProviderAPIConfig
config, IdentityProviderRequestOptions
provider, globalObject가 주어지면 다음 단계를 실행합니다. 반환값은 boolean입니다.
-
단언: 이 단계는 병렬로 실행됩니다.
-
metadata를 클라이언트 메타데이터 가져오기 알고리즘으로 config, provider, globalObject로 계산합니다.
-
사용자에게 계정 생성 의사 확인 프롬프트를 표시합니다. 사용자 에이전트는 UI 스타일을 결정할 때
IdentityProviderBranding
을 사용할 수 있습니다. 추가로:-
metadata가 실패가 아니고, metadata["
privacy_policy_url
"] 이 정의되어 있으며, provider의clientId
가 account["approved_clients
"] 목록에 없으면, 사용자 에이전트는 반드시 metadata["privacy_policy_url
"] 링크를 표시해야 합니다. -
metadata가 실패가 아니고, metadata["
terms_of_service_url
"] 이 정의되어 있으며, provider의clientId
가 account["approved_clients
"] 목록에 없으면, 사용자 에이전트는 반드시 metadata["terms_of_service_url
"] 링크를 표시해야 합니다. -
사용자 에이전트는
context
를 사용해 다이얼로그를 커스터마이징할 수 있습니다.
-
-
사용자가 허가하지 않으면 false 반환
-
RP와 IdP 계정 간 연결 생성 알고리즘을 provider, account, globalObject로 실행합니다.
-
true 반환
IdentityProviderAPIConfig
config,
IdentityProviderRequestOptions
provider가 주어지면 다음 단계를 실행합니다. 반환값은 IdentityProviderClientMetadata
또는 실패입니다.
-
clientMetadataUrl을 manifest URL 계산 알고리즘으로 provider, config["
client_metadata_endpoint
"], globalObject로 계산합니다. -
clientMetadataUrl이 실패면, 실패 반환
-
request를 다음과 같이 새 request로 생성합니다:
- url
-
clientMetadataUrl
- redirect mode
-
"error"
- client
-
null
- window
-
"no-window"
- service-workers mode
-
"none"
- destination
-
"webidentity"
- origin
- header list
-
하나의 헤더만 포함된 리스트로, name은
Accept
로, value는application/json
로 설정됨 - credentials mode
-
"omit"
- mode
-
"no-cors"
모든 request가 mode "user-agent-no-cors"로 생성되도록 명세 업데이트 필요. 관련 PR 참고.
-
metadata를 null로 설정합니다.
-
Fetch request 알고리즘을 request, globalObject로 실행하고, processResponseConsumeBody는 response response, responseBody를 받아 다음 단계로 실행합니다:
-
json을 extract the JSON fetch response 알고리즘으로 response, responseBody에서 추출합니다.
-
변환 json을
IdentityProviderClientMetadata
타입으로 변환해 metadata에 저장합니다. -
위 두 단계 중 예외가 발생하면 metadata를 실패로 설정합니다.
-
-
metadata가 설정될 때까지 기다립니다.
-
metadata를 반환합니다.
dictionary {
IdentityProviderClientMetadata USVString privacy_policy_url ;USVString terms_of_service_url ; };
2.3.9. 도움 알고리즘
다음의 도움 알고리즘들은 FedCM 플로우 중에 사용됩니다.
USVString
stringUrl, globalObject, 선택적 baseUrl(기본값 null)이 주어지면 다음 단계를 실행합니다. 반환값은 URL
또는 실패입니다.
-
configUrl을 null로 설정합니다.
-
글로벌 태스크 큐를 DOM 조작 태스크 소스에 globalObject를 이용해 큐잉하여, configUrl을 url parser를 stringUrl과 baseUrl로 실행한 결과로 설정합니다.
참고: url parser는 태스크 내에서 실행되어야 하므로, 병렬로 실행하지 않습니다.
-
configUrl이 설정될 때까지 기다립니다.
-
configUrl을 반환합니다.
-
글로벌 태스크 큐를 네트워크 태스크 소스에 globalObject를 이용해 큐잉하여 다음을 실행합니다:
-
Fetch request를 processResponseConsumeBody를 processResponseConsumeBody로 설정하여 실행
-
IdentityProviderRequestOptions
provider, string manifestString, globalObject가 주어지면 다음 단계를 실행합니다.
반환값은 URL 또는 실패입니다.
-
configUrl을 parse url 알고리즘으로 provider의
configURL
및 globalObject로 계산합니다. -
manifestUrl을 parse url 알고리즘으로 manifestString(상대 URL), globalObject, configUrl(base URL)로 실행합니다.
-
manifestUrl이 설정될 때까지 기다립니다.
참고: manifest 문자열은 절대 URL 또는 상대 URL 모두 허용됩니다.
-
manifestUrl이 실패면 실패 반환
-
manifestUrl이 configUrl과 동일 오리진이 아니면 실패 반환
-
manifestUrl이 신뢰할 수 있는 URL이 아니면 실패 반환
-
manifestUrl 반환
-
단언: 이 단계는 네트워크 태스크 소스에서 실행됩니다.
-
response가 네트워크 오류이거나, status가 ok status가 아니면, "
NetworkError
"DOMException
을 throw합니다. -
mimeType을 MIME 타입 추출 알고리즘으로 response의 header list에서 추출합니다.
-
mimeType이 실패거나 JSON MIME Type이 아니면, "
NetworkError
"DOMException
을 throw합니다. -
json을 JSON 바이트를 JavaScript 값으로 파싱 알고리즘으로 responseBody를 전달하여 계산합니다.
-
json이 파싱 예외면 "
NetworkError
"DOMException
을 throw합니다. -
json 반환
IdentityProviderAPIConfig
config, IdentityProviderConfig
provider, globalObject가 주어지면 다음 단계를 실행합니다. 반환값은 성공 또는 실패입니다.
-
단언: 이 단계는 병렬로 실행됩니다.
-
loginUrl을 null로 설정합니다.
-
글로벌 태스크 큐를 DOM 조작 태스크 소스에 globalObject를 이용해 큐잉하여, loginUrl을 url parser를 config.
login_url
로 실행한 결과로 설정합니다. -
loginUrl이 null이 아닐 때까지 기다립니다.
-
단언: loginUrl은 실패가 아님(사용자 에이전트가 config.
login_url
이 유효한 URL임을 미리 확인). -
queryList를 새 리스트로 생성합니다.
-
provider의
loginHint
값이 비어 있지 않으면, append ("login_hint",loginHint
) 를 queryList에 추가합니다. -
provider의
domainHint
값이 비어 있지 않으면, append ("domain_hint",domainHint
) 를 queryList에 추가합니다. -
queryList가 empty가 아니면:
-
queryParameters를 urlencoded serializer 알고리즘으로 queryList를 사용해 계산합니다.
-
loginUrl의 query가 null 또는 비어 있지 않으면, queryParameters 앞에 "&"를 붙입니다.
-
queryParameters를 loginUrl의 query에 추가합니다.
-
-
새로운 최상위 traversable 생성 알고리즘을 loginUrl로 실행합니다.
-
사용자 에이전트는 브라우징 컨텍스트 기능 설정 또는 구현 상의 방법으로 traversable의 표시를 조정할 수 있습니다.
-
다음 조건 중 하나가 될 때까지 기다립니다:
-
사용자가 브라우징 컨텍스트를 닫으면: 실패 반환
-
IdentityProvider
.close
함수가 이 traversable의 컨텍스트에서 호출되면:-
traversable을 닫습니다.
-
loginStatus를 로그인 상태 가져오기 알고리즘으로
login_url
의 origin으로 설정합니다.참고: IDP 로그인 플로우는 로그인 중 JavaScript 또는 HTTP 헤더 API를 통해 이 값을 logged-in으로 설정할 수 있습니다. 또한, 다른 브라우징 컨텍스트에서 변경될 수도 있습니다.
-
loginStatus가 logged-in이면 성공 반환
-
그 외에는 실패 반환
-
-
2.4. IdentityProvider 인터페이스
이 명세는 IdentityUserInfo
딕셔너리와 IdentityProvider
인터페이스를 도입합니다:
dictionary {
IdentityUserInfo USVString ;
USVString ;
name USVString ;
givenName USVString ; }; [
picture Exposed =Window ,SecureContext ]interface {
IdentityProvider static undefined ();
close static Promise <sequence <IdentityUserInfo >>(
getUserInfo IdentityProviderConfig ); };
config
확정 필요 IdentityProvider
가 getUserInfo()
메서드의 올바른 위치인지.
close
함수는 브라우저에 로그인 플로우가 끝났음을 알리기 위해 제공됩니다. 이 함수가 헤더 외에 존재하는 이유는, 이미 사용자가 로그인되어 있더라도 로그인 플로우가 끝난 것이 아닐 수 있기 때문입니다.
예를 들어, IDP가 사용자에게 전화번호 인증을 추가로 요구할 수 있습니다. 이런
플로우를 허용하기 위해, IDP는 플로우가 완전히 끝날 때 close
를 호출해야 합니다.
자세한 내용은 IDP 로그인 다이얼로그 표시 알고리즘을 참고하세요.
IdentityUserInfo
는 사용자 계정 정보를 나타냅니다. 이 정보는 사용자가 이미 FedCM API를 통해 RP에
로그인한 경우에 IDP에 노출됩니다. 즉, connected accounts set에 (RP, IDP, account) 트리플이 존재하면 노출됩니다. 이 정보는 accounts endpoint에서 수신한 내용과 일치합니다. IDP는 자신의 configURL
의
origin에 맞는 iframe에서 getUserInfo()
정적 메서드를 호출하여 이 정보를 얻을 수 있습니다.
const userInfo= await IdentityProvider. getUserInfo({ configUrl: "https://idp.example/fedcm.json" , clientId: "client1234" }); if ( userInfo. length> 0 ) { // 반환된 계정들을 어떻게 표시할지는 IDP의 자유입니다. const name= userInfo[ 0 ]. name; const givenName= userInfo[ 0 ]. givenName; const displayName= givenName? givenName: name; const picture= userInfo[ 0 ]. picture; const email= userInfo[ 0 ]. email; }
getUserInfo()
메서드가 IdentityProviderConfig
provider와 함께 호출될 때, 다음 단계를 수행한다:
-
globalObject를 현재 글로벌 객체로 한다.
-
document를 globalObject의 연결된 문서로 한다.
-
document가 identity-credentials-get 정책 제어 기능을 사용할 수 없다면, "
NotAllowedError
"DOMException
을 throw한다. -
connected accounts set에 다음과 같이 compute the connected account key 알고리즘으로 account, provider, globalObject의 결과가 포함된 account가 없다면, promise를 "
NetworkError
"DOMException
으로 reject한다. 이 검사는 connected accounts set을 순회하거나 별도의 자료 구조를 유지하여 빠르게 조회할 수 있다. -
configUrl을 parse url 알고리즘으로 provider의
configURL
및 globalObject로 계산한다. -
configUrl이 실패이면, "
InvalidStateError
"DOMException
을 throw한다. -
document의 origin이 configUrl의 origin과 동일하지 않으면, "
InvalidStateError
"DOMException
을 throw한다. -
Content Security Policy Level 3의 connect-src 지시어로 configUrl에 대해 체크한다. 실패하면, "
NetworkError
"DOMException
을 throw한다. -
globalObject의 navigable이 top-level traversable이라면, "
NetworkError
"DOMException
을 throw한다. -
사용자가 globalObject의 navigable의 top-level traversable에서 FedCM API를 비활성화했다면, "
NetworkError
"DOMException
을 throw한다. -
promise를 새
Promise
로 한다. -
다음 단계를 병렬로 실행한다:
-
config를 fetch the config file 알고리즘으로 provider, globalObject를 사용해 계산한다.
-
config이 실패이면, promise를 새 "
NetworkError
"DOMException
으로 reject한다. -
accountsList를 fetch the accounts 알고리즘으로 config, provider, globalObject로 계산한다.
-
hasAccountEligibleForAutoReauthentication를 false로 한다.
-
accountsList의 각 account에 대하여:
-
account["
approved_clients
"] 가 비어 있지 않고, provider의clientId
가 포함되어 있지 않으면, continue.참고: 이것은 IDP가 계정의 returning 여부를 오버라이드할 수 있게 한다. 예를 들어 사용자가 계정을 out of band로 연결 해제한 경우 등에 유용할 수 있다.
-
account가 eligible for auto reauthentication라면, provider, globalObject와 함께 hasAccountEligibleForAutoReauthentication를 true로 설정한다.
-
-
hasAccountEligibleForAutoReauthentication가 false라면, promise를 새 "
NetworkError
"DOMException
으로 reject한다. -
userInfoList를 새 리스트로 한다.
-
accountsList의 각 account에 대하여:
-
Append
IdentityUserInfo
를 userInfoList에 다음 값으로 추가한다:
-
-
3. 아이덴티티 제공자 HTTP API
이 섹션은 규범적이지 않습니다.
IDP는 여러 HTTP 엔드포인트를 제공합니다:
-
§ 3.1 웰노운 파일 (Manifest를 가리킴)
-
약속된 위치에 있는 § 3.2 설정 파일 (다른 엔드포인트를 가리킴)
-
§ 3.4 클라이언트 메타데이터 엔드포인트
-
§ 3.6 연결 해제 엔드포인트 (IDP가
disconnect
를 지원하는 경우)
FedCM API는 사이트가 브라우저에게 여러 네트워크 요청을 실행하도록 요구할 수 있게 해줍니다. 브라우저는 사용자가 FedCM을 통해 사이트를 방문할 때 공격자가 IDP로 위장하여 사용자를 추적하지 못하도록 실행해야 합니다. 아래 표는 수행되는 네트워크 요청에 대한 정보를 제공합니다:
엔드포인트 | 쿠키 | client_id | origin |
manifests | 아니오 | 아니오 | 아니오 |
accounts_endpoint | 예 | 아니오 | 아니오 |
client_metadata_endpoint | 아니오 | 예 | 예 |
id_assertion_endpoint | 예 | 예 | 예 |
disconnect_endpoint | 예 | 예 | 예 |
3.1. 웰노운 파일
참고: 브라우저는 웰노운 파일을 § 7.3.1 Manifest Fingerprinting을 방지하기 위해 사용합니다.
IDP는 미리 정해진 위치, 즉 ".well-known" 경로의 "web-identity" 파일에 웰노운 파일을 노출합니다.
웰노운 파일은 설정 파일 가져오기 알고리즘에서 가져옵니다:
(a) 쿠키 없이,
(b) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(c) RP를 Origin이나 Referer 헤더에 노출하지 않음
예시:
GET /.well-known/web-identity HTTP / 1.1 Host : idp.example Accept : application/json Sec-Fetch-Dest : webidentity
이 파일은 IdentityProviderWellKnown
JSON 객체로 파싱됩니다.
IdentityProviderWellKnown
JSON 객체의 의미는 다음과 같습니다:
provider_urls
(필수), 타입: sequence<USVString>-
유효한 § 3.2 설정 파일을 가리키는 URL 목록입니다.
3.2. 설정 파일
설정 파일은 IDP가 제공하는 다른 엔드포인트를 발견할 수 있는 장치 역할을 합니다.
설정 파일은 설정 파일 가져오기 알고리즘에서 가져옵니다:
(a) 쿠키 없이,
(b) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(c) RP를 Origin이나 Referer 헤더에 노출하지 않음,
(d) HTTP 리다이렉트를 따라가지 않음
예시:
응답 바디는 반드시 예외 없이 IdentityProviderAPIConfig
타입으로 변환될 수 있는 JSON 객체여야 합니다.
IdentityProviderAPIConfig
객체의 멤버 의미는 다음과 같습니다:
accounts_endpoint
, 타입: USVString-
HTTP API를 가리키는 URL로, § 3.3 계정 엔드포인트 API를 준수해야 합니다.
client_metadata_endpoint
, 타입: USVString-
HTTP API를 가리키는 URL로, § 3.4 클라이언트 메타데이터 API를 준수해야 합니다.
id_assertion_endpoint
, 타입: USVString-
HTTP API를 가리키는 URL로, § 3.5 아이덴티티 어설션 엔드포인트 API를 준수해야 합니다.
disconnect_endpoint
, 타입: USVString-
HTTP API를 가리키는 URL로, § 3.6 연결 해제 엔드포인트 API를 준수해야 합니다.
branding
, 타입: IdentityProviderBranding-
IdentityProviderBranding
옵션의 집합입니다.
IdentityProviderBranding
을 통해 IDP는 브랜딩 선호도를 표현할 수 있으며, 이는 사용자
에이전트가 권한 프롬프트를 맞춤화하는데 사용할 수 있습니다.
참고: 브랜딩 선호도는 UI 구조에 대해 구체적이지 않고 추상적으로 설계되었습니다. 이는 다양한 사용자 에이전트가 각기 다른 UI 경험을 제공할 수 있도록 하고, 시간이 지나며 독립적으로 진화할 수 있도록 하기 위함입니다.
멤버의 의미는 다음과 같습니다:
background_color
, 타입: USVStringcolor
, 타입: USVStringicons
, 타입: sequence<IdentityProviderIcon>-
IdentityProviderIcon
객체의 목록입니다. name
, 타입: USVString-
IDP를 사용자가 인지할 수 있는 이름입니다.
참고: 브랜딩 선호도는 UI 구조에 대해 구체적이지 않고 추상적으로 설계되었습니다. 이는 다양한 사용자 에이전트가 각기 다른 UI 경험을 제공할 수 있도록 하고, 시간이 지나며 독립적으로 진화할 수 있도록 하기 위함입니다.
IdentityProviderIcon
의 멤버 의미는 다음과 같습니다:
url
, 타입: USVString-
아이콘 이미지를 가리키는 URL로, 반드시 정사각형이며 단일 해상도여야 합니다(.ico의 멀티 해상도 불가). 아이콘은 maskable 명세를 따라야 합니다.
size
, 타입: unsigned long-
정사각형 아이콘의 너비/높이입니다. 아이콘이 벡터 그래픽(SVG 등)인 경우 size는 생략할 수 있습니다.
참고: 사용자 에이전트는 개발자가 제공한 아이콘에 대해 정사각형 영역을 예약합니다. 정사각형이 아닌 아이콘이 제공되면, 사용자 에이전트는 아이콘을 표시하지 않거나, 잘라서 정사각형 일부만 표시하거나, 정사각형으로 변환해 표시할 수 있습니다.
color는 CSS <color> 문법의 부분집합으로, <hex-color>, hsl(), rgb() 및 <named-color>를 포함합니다.
예시:
{ "accounts_endpoint" : "/accounts" , "client_metadata_endpoint" : "/metadata" , "id_assertion_endpoint" : "/assertion" , "disconnect_endpoint" : "/disconnect" , "branding" : { "background_color" : "green" , "color" : "#FFEEAA" , "icons" : [{ "url" : "https://idp.example/icon.ico" , "size" : 25 }], "name" : "IDP Example" } }
3.3. 계정 엔드포인트
계정 엔드포인트는 사용자가 IDP에 보유한 계정 목록을 제공합니다.
계정 엔드포인트는 계정 가져오기 알고리즘에서 호출됩니다:
(a) IDP 쿠키 포함,
(b) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(c) RP를 Origin이나 Referer 헤더에 노출하지 않음,
(d) HTTP 리다이렉트를 따라가지 않음
예시:
GET /accounts_list HTTP / 1.1 Host : idp.example Accept : application/json Cookie : 0x23223 Sec-Fetch-Dest : webidentity
응답 바디는 반드시 예외 없이 변환 가능한 IdentityProviderAccountList
JSON 객체여야 합니다.
각 IdentityProviderAccount
는
다음 의미의 멤버를 가집니다:
id
, 타입 USVString-
계정의 고유 식별자입니다.
name
, 타입 USVString-
사용자의 전체 이름입니다.
email
, 타입 USVString-
사용자의 이메일 주소입니다.
given_name
, 타입 USVString-
사용자의 이름(성 제외)입니다.
picture
, 타입 USVString-
계정 프로필 사진의 URL입니다.
approved_clients
, 타입 sequence<USVString>-
이 계정에 이미 등록된 RP 목록입니다(
clientId
와 비교). 회원가입 허가 요청에서 개인정보처리방침과 서비스약관 표시 여부를 제어하는데 사용됩니다. login_hints
, 타입 sequence<DOMString>-
이 계정에 해당하는 모든 로그인 힌트 문자열 목록입니다.RP는
loginHint
를 사용하여 해당 값과 일치하는 계정만 사용자에게 보여줄 수 있습니다. domain_hints
, 타입 sequence<DOMString>-
이 계정에 해당하는 모든 도메인 힌트 문자열 목록입니다.RP는
domainHint
를 사용하여 해당 값과 일치하거나 도메인 힌트를 포함하는 계정만 사용자에게 보여줄 수 있습니다.
예시:
{ "accounts" : [{ "id" : "1234" , "given_name" : "John" , "name" : "John Doe" , "email" : "john_doe@idp.example" , "picture" : "https://idp.example/profile/123" , "approved_clients" : [ "123" , "456" , "789" ], "login_hints" : [ "john_doe" ], "domain_hints" : [ "idp.example" ], }, { "id" : "5678" , "given_name" : "Johnny" , "name" : "Johnny" , "email" : "johnny@idp.example" , "picture" : "https://idp.example/profile/456" , "approved_clients" : [ "abc" , "def" , "ghi" ], "login_hints" : [ "email=johhny@idp.example" , "id=5678" ], "domain_hints" : [ "idp.example" ], }] }
사용자가 로그인되어 있지 않을 때의 IDP API 응답을 명확히 할 것
3.4. 클라이언트 메타데이터
클라이언트 메타데이터 엔드포인트는 RP에 대한 메타데이터를 제공합니다.
클라이언트 메타데이터 엔드포인트는 클라이언트 메타데이터 가져오기 알고리즘에서 호출됩니다:
(a) 쿠키 없이,
(b) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(c) Origin 헤더에 RP의 오리진 포함,
(d) HTTP 리다이렉트를 따라가지 않음
사용자 에이전트는 client_id도 함께 전달합니다.
예시:
GET /client_medata?client_id=1234 HTTP / 1.1 Host : idp.example Origin : https://rp.example/ Accept : application/json Sec-Fetch-Dest : webidentity
응답 바디는 반드시 예외 없이 변환 가능한 IdentityProviderClientMetadata
JSON 객체여야 합니다.
IdentityProviderClientMetadata
객체의 멤버 의미는 다음과 같습니다:
privacy_policy_url
, 타입 USVString-
RP의 개인정보처리방침 링크입니다.
terms_of_service_url
, 타입 USVString-
RP의 서비스약관 링크입니다.
예시:
{ "privacy_policy_url" : "https://rp.example/clientmetadata/privacy_policy.html" , "terms_of_service_url" : "https://rp.example/clientmetadata/terms_of_service.html" }
3.5. 아이덴티티 어설션 엔드포인트
아이덴티티 어설션 엔드포인트는 사용자에 대한 서명된 어설션을 포함하는 새로운 토큰을 발급하는 역할을 합니다.
아이덴티티 어설션 엔드포인트는 아이덴티티 어설션 가져오기 알고리즘에서 호출됩니다:
(a) POST 요청으로,
(b) IDP 쿠키 포함,
(c) Origin 헤더에 RP의 오리진 포함,
(d) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(e) HTTP 리다이렉트를 따라가지 않음
요청 바디 application/x-www-form-urlencoded
에는 다음 파라미터가 포함됩니다:
client_id
-
RP의 고유 식별자(IDP에서 발급)
nonce
-
요청 nonce 값
account_id
-
선택된 계정의 식별자
disclosure_text_shown
-
사용자 에이전트가 IDP가 RP에 어떤 정보를 공유하는지(예: "idp.example이 rp.example에 이름, 이메일을 공유합니다...")를 명시적으로 사용자에게 보여줬는지 여부입니다. 신규 사용자 회원가입 허가 요청 알고리즘에서 사용됩니다. 서비스 약관 및 개인정보처리방침을 사용자에게 실제로 표시했음을 보장하기 위해 사용됩니다.
예시:
POST /fedcm_assertion_endpoint HTTP / 1.1 Host : idp.example Origin : https://rp.example/ Content-Type : application/x-www-form-urlencoded Cookie : 0x23223 Sec-Fetch-Dest : webidentity account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true
clientId
로
표현되는지 확인해야 합니다. clientId
는
IDP별로 관리되므로, 사용자 에이전트는 이 검사를 할 수 없습니다.
응답 바디는 반드시 예외 없이 변환 가능한 IdentityProviderToken
JSON 객체여야 합니다.
각 IdentityProviderToken
는
다음 의미의 멤버를 가집니다:
token
, 타입 USVString-
최종 발급된 토큰 값입니다.
token
의
내용은 사용자 에이전트에게 불투명하며, IDP가 RP 로그인에 필요한 정보를 자유롭게 포함할 수 있습니다. 따라서 RP가 token
을
검증하는 주체가 되어야 하며, 관련 토큰 검증 알고리즘을 사용해야 합니다. 예시로 OIDC Connect Core
§ IDTokenValidation가 있습니다.
참고: IDP 입장에서는 계정의 이동성(portability)을 어떻게 구현할지 고민할 가치가 있습니다. 이동성은 IDP가 다양한 방법을 선택할 수 있으며, (예: OIDC의 계정 이관 등) 완전히 IDP의 결정에 따라 달라집니다.
예시:
3.6. 연결 해제 엔드포인트
연결 해제 엔드포인트는 이전에
생성된 RP와 IDP 계정 간의 연합 로그인 연결을 끊고, 해당 계정의 id
를 반환하여 사용자 에이전트가 connected accounts set에서 제거할 수 있도록 합니다.
연결 해제 엔드포인트는 disconnect
메서드가 호출될 때 요청됩니다:
(a) POST 요청으로,
(b) IDP 쿠키 포함,
(c) Origin 헤더에 RP 오리진 포함,
(d) Sec-Fetch-Dest 헤더를 webidentity
로
설정,
(e) HTTP 리다이렉트를 따라가지 않음,
(f) "cors" 모드로 요청됨.
요청 바디 application/x-www-form-urlencoded
에는 다음이 포함됩니다:
예시:
POST /fedcm_disconnect_endpoint HTTP / 1.1 Host : idp.example Origin : https://rp.example/ Content-Type : application/x-www-form-urlencoded Cookie : 0x23223 Sec-Fetch-Dest : webidentity client_id=client1234&account_hint=hint12
연결 해제가 실패하면 IDP는 에러를 반환할 수 있습니다. 성공하면
응답 바디는 반드시 예외 없이 변환 가능한 DisconnectedAccount
JSON 객체여야 합니다.
account_id
, 타입 USVString-
연결 해제에 성공한 계정의
id
값입니다.
IDP는 account_id
를 반드시 반환해야 합니다. 이는 account_hint
와
다를 수 있으며,
사용자 에이전트가 connected accounts set에서 계정을 해제할 때 id
값을 사용합니다. 만약 IDP가 에러를 반환하거나
사용자
에이전트가 IDP가 제공한 ID로 계정을 찾지 못하면, 관련 (RP, IDP)에 연결된 모든 계정이 connected accounts set에서 제거됩니다.
4. 권한 정책 통합
FedCM은 정책 제어 기능을 정의하며, 문자열
"identity-credentials-get"
로
식별됩니다.
이 기능의 기본 허용 목록은 "self"
입니다.
Document
의
permissions policy는 해당 문서 내의 어떤 콘텐츠가 브라우저 API를 통해 credential 객체를 얻을 수 있는지 결정합니다.
navigator.credentials.get({identity:..., ...})
를 identity-credentials-get
기능을 사용할 수 없는 문서에서 호출하면,
promise reject가 발생하며 "NotAllowedError
"
DOMException
이
반환됩니다.
이 제한은 Permissions Policy에서 설명된 메커니즘으로 제어할 수 있습니다.
참고: Credential Management Level 1에서
정의된 알고리즘이 실제 권한 정책 평가를 수행합니다. 이러한 정책 평가는 현재 설정 객체에 접근할 때 이뤄져야 하기 때문입니다. 이 명세에 의해 수정된 내부 메서드는 그런 접근이 없으며, CredentialsContainer
의
Request a Credential
추상 연산에서 병렬로 호출되기
때문입니다.
5. 사용자 에이전트 자동화
사용자 에이전트 자동화 및 웹사이트 테스트를 위해, 이 문서는 아래 WebDriver 확장 명령을 정의하여 활성 FedCM 다이얼로그와 상호작용할 수 있습니다.
5.1. 확장 기능
아래에 정의된 확장 명령의 사용 가능성을 광고하기 위해 새로운 확장 기능(capability)을 정의합니다.
Capability | Key | Value Type | Description |
---|---|---|---|
Federated Credential Management Support | "fedcm:accounts"
| boolean | 엔드포인트 노드가 모든 Federated Credential Management 명령을 지원하는지 여부를 나타냅니다. |
기능(capabilities) 검증 시, "fedcm:accounts"
와
value
를 검증하는 확장 전용 하위 단계는 다음과 같습니다:
-
value
가 boolean이 아니면, WebDriver 오류를 error code invalid argument와 함께 반환합니다. -
그 외에는
deserialized
를value
로 설정합니다.
기능 매칭 시, "fedcm:accounts"
와 value
를
매칭하는 확장 전용 단계는 다음과 같습니다:
-
value
가true
이고 엔드포인트 노드가 Federated Credential Management 명령 중 하나라도 지원하지 않으면, 매칭 실패입니다. -
그 외에는 매칭 성공입니다.
5.2. 다이얼로그 취소
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/fedcm/canceldialog
|
-
현재 FedCM 다이얼로그가 열려 있지 않으면, WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
다이얼로그를 닫고, IdentityCredential 생성 알고리즘을 사용자가 계정을 선택하지 않고 다이얼로그를 취소한 것처럼 계속 진행합니다.
-
success와 데이터
null
을 반환합니다.
5.3. 계정 선택
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/fedcm/selectaccount
|
-
parameters가 JSON Object가 아니면 WebDriver 오류를 error code invalid argument와 함께 반환합니다.
-
현재 FedCM 다이얼로그가 열려 있지 않으면 WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
accountIndex를 "accountIndex"라는 이름의 property를 parameters에서 가져온 결과로 설정합니다.
-
accountIndex가
undefined
이거나 0보다 작거나, 현재 플로우에서 사용자가 선택할 수 있는 계정 수보다 크거나 같으면 WebDriver 오류를 error code invalid argument와 함께 반환합니다. -
다이얼로그를 닫고, IdentityCredential 생성 알고리즘을 accountIndex로 지목된 계정을 사용자가 선택하고(필요하다면) 회원가입 허가를 승인한 것처럼 계속 진행합니다.
-
success와 데이터
null
을 반환합니다.
5.4. 다이얼로그 버튼 클릭
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/fedcm/clickdialogbutton
|
-
parameters가 JSON Object가 아니면 WebDriver 오류를 error code invalid argument와 함께 반환합니다.
-
dialogButton을 "dialogButton"라는 property를 parameters에서 가져온 결과로 설정합니다.
-
dialogButton이 "
ConfirmIdpLoginContinue
"가 아니면 WebDriver 오류를 error code invalid argument와 함께 반환합니다. -
현재 FedCM 다이얼로그가 열려 있지 않거나 해당 다이얼로그가 IDP 로그인 확인 다이얼로그가 아니면 WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
사용자가 IDP 로그인 확인 다이얼로그에서 "계속" 버튼을 클릭한 것처럼 동작하고 로그인 플로우를 시작합니다.
-
success와 데이터
null
을 반환합니다.
5.5. 계정 목록
HTTP Method | URI Template |
---|---|
GET | /session/{session id}/fedcm/accountlist
|
-
현재 FedCM 다이얼로그가 열려 있지 않으면, WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
accounts를 현재 플로우에서 사용자가 선택할 수 있거나 선택할 수 있었던 계정 목록으로 설정합니다.
-
list를 빈 리스트로 설정합니다.
-
accounts의 각 account에 대해:
-
accountState를 compute the connection status 알고리즘으로 account, 해당
IdentityProviderRequestOptions
를 사용하여 계산합니다. -
Append를 사용해 아래 속성을 가진 dictionary를 list에 추가합니다:
-
accountId
는 account의id
로 설정 -
email
은 account의email
로 설정 -
name
은 account의name
로 설정 -
givenName
은 account의given_name
이 있으면 그 값으로 설정 -
pictureUrl
은 account의picture
가 있으면 그 값으로 설정 -
idpConfigUrl
은 해당 계정이 속한 IDP의configURL
로 설정 -
loginState
는 accountState가 disconnected이면"SignUp"
, 아니면"SignIn"
으로 설정 -
termsOfServiceUrl
은 값이 제공되고loginState
가"SignUp"
일 때만terms_of_service_url
로, 아니면undefined
로 설정 -
privacyPolicyUrl
은 값이 제공되고loginState
가"SignUp"
일 때만privacy_policy_url
로, 아니면undefined
로 설정
-
-
-
success와 데이터 list를 반환합니다.
5.6. 타이틀 가져오기
HTTP 메서드 | URI 템플릿 |
---|---|
GET | /session/{session id}/fedcm/gettitle
|
참고: 이 명령은 자동화가 context api가 올바르게 적용되었는지 검증하는 데 사용됩니다
-
현재 FedCM 다이얼로그가 열려 있지 않으면, WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
data를 다음과 같은 속성을 가진 객체(dictionary)로 설정합니다:
-
title
을 열린 다이얼로그의 타이틀로 설정 -
subtitle
을 열린 다이얼로그의 서브타이틀로(있다면) 설정
-
-
success와 데이터 data를 반환합니다.
5.7. 다이얼로그 타입 가져오기
HTTP 메서드 | URI 템플릿 |
---|---|
GET | /session/{session id}/fedcm/getdialogtype
|
-
현재 FedCM 다이얼로그가 열려 있지 않으면, WebDriver 오류를 error code no such alert와 함께 반환합니다.
-
type을 문자열 "
AutoReauthn
"(사용자가 자동 재인증 중일 때), "AccountChooser
"(계정 선택 다이얼로그일 때), "ConfirmIdpLogin
"(IDP 로그인 확인 다이얼로그일 때) 중 하나로 설정합니다. -
success와 데이터 type을 반환합니다.
5.8. 지연 활성화 설정
HTTP 메서드 | URI 템플릿 |
---|---|
POST | /session/{session id}/fedcm/ setdelayenabled
|
-
parameters가 JSON Object가 아니면 WebDriver 오류를 error code invalid argument와 함께 반환합니다.
-
enabled를 "enabled"라는 property를 parameters에서 가져온 결과로 설정합니다.
-
enabled가
undefined
이거나 boolean이 아니면 WebDriver 오류를 error code invalid argument와 함께 반환합니다. -
enabled가 false면 promise reject 지연을 비활성화하고, 아니면 다시 활성화합니다.
-
success와 데이터
null
을 반환합니다.
5.9. 쿨다운 리셋
HTTP 메서드 | URI 템플릿 |
---|---|
POST | /session/{session id}/fedcm/resetcooldown
|
-
사용자 에이전트가 쿨다운(다이얼로그 닫은 뒤 일정 시간 동안 API를 비활성화) 지연을 사용하면, 이 명령은 쿨다운을 리셋하여 다음 FedCM 호출이 다시 성공할 수 있게 합니다.
-
success와 데이터
null
을 반환합니다.
6. 보안
이 섹션은 FedCM API의 보안 고려사항을 일부 제공합니다. § 7 개인정보 관련 사항은 별도의 섹션을 참고하세요.
6.1. 콘텐츠 보안 정책
FedCM API가 처음 트리거하는 fetch는 공개된 manifest 리스트와 설정 파일입니다. 악의적인 스크립트가 RP에 포함되어(그리고 RP로 동작하며) FedCM API를 악성 IDP로 호출한다고 가정합니다. 만약 호출이 성공하면, 이는 악성 IDP에서 로그인 옵션이 포함된 브라우저 UI가 RP에 나타나게 됩니다. 이 악성 IDP는 사용자를 속이려 할 수 있습니다. 이에 대한 보호는 Content Security Policy Level 3 체크입니다. 악성 IDP manifest 오리진이 Content Security Policy Level 3의 allowlist에 포함되지 않으므로, FedCM UI가 나타나지 않습니다. 이후 fetch들은 설정 파일 기준으로 동일 오리진이거나 최소 설정 파일의 내용에 따라 달라지므로 추가적인 체크가 필요하지 않습니다.
동일 오리진이 아닌 fetch에는 예를 들어 브랜드 아이콘이 있습니다. 사용자 에이전트는 이 fetch에 대해 Content Security Policy Level 3 체크를 하지 않습니다. 이 이미지는 manifest에서 직접 지정되며, 렌더링은 사용자 에이전트가 담당하므로 해당 이미지는 RP 사이트에 영향을 미치거나 RP에서 접근할 수 없습니다.
6.2. Sec-Fetch-Dest 헤더
FedCM API는 IDP에 대해 여러 비정적 엔드포인트를 도입하므로 XSS 공격으로부터
보호가 필요합니다. 이를 위해 FedCM API는 Sec-Fetch-Dest 헤더에 금지된
request-header의 새 값을 도입합니다. FedCM API로 트리거된 요청은 이 헤더 값으로 webidentity
를 사용합니다. 이 값은 임의의
웹사이트가 설정할 수 없으므로, IDP는 요청이 실제 FedCM 브라우저에서 기원했다는
것을 확신할 수 있습니다. IDP는 credentialed 요청에서 반드시 이 헤더 값을
확인해야 하며, 이를 통해 요청이 사용자 에이전트에서 FedCM API로 시작된 것임을 보장합니다. 악의적인 행위자는 FedCM API 요청을 스팸처럼 보낼 수 없으므로, 이것만으로 새 IDP 엔드포인트에 충분한 보호가 됩니다.
6.3. CORS 헤더
FedCM API는 아이덴티티 어설션 엔드포인트의 응답을 RP에 공유할 수 있게 합니다. 이를 위해, 이 엔드포인트를 fetch할 때 "cors" 모드를 사용해 IDP가 명시적으로 동의해야 합니다. 또한, 서버가 Sec-Fetch-Dest를 실수로 무시하는 경우에도 CORS가 없으면 fetch가 실패하므로 추가 보호가 됩니다.
6.4. 브라우저 UI 사칭 방지
FedCM API는 새로운(신뢰된) 사용자 에이전트 UI를 도입하며, 사용자 에이전트는 이 UI를 페이지 내용 위에 완전히 덮어 표시할 수 있습니다(이 UI를 트리거한 것이 페이지이기 때문). 이로 인해 악의적인 사이트가 FedCM UI를 모방해 사용자가 신뢰하는 브라우저 UI라고 믿게 하고, 사용자가 브라우저에만 제공하는 정보를(예: 다른 사이트의 아이디/비밀번호 등) 탈취하려는 우려가 있습니다. 하지만 FedCM UI는 IDP의 사용자 계정 메타데이터를 사용해 악성 웹사이트가 접근할 수 없습니다. 악성 사이트라면 사용자가 이미 노출되지 않은 이상 계정 정보를 알 수 없습니다. 사이트가 사용자 신원을 어느 정도 추측할 수는 있지만, 브라우저는 모방하기 어렵고, 당사 도메인이 명확하게 표시된 UI를 제공하도록 권장됩니다. 공격자가 iframes 등 콘텐츠 영역 UI만으로 브라우저를 사칭해 민감 정보를 탈취하려 해도 FedCM UI와 명백히 다릅니다. 또한 FedCM UI는 최상위 프레임(혹은 명시적 허가된 iframe)에서만 표시되므로, 특권 UI는 최상위 프레임이 원할 때만 표시됩니다. 몰래 iframe이 주요 콘텐츠 위에 FedCM UI를 강제로 띄울 수 없습니다.
7. 개인정보
이 섹션은 웹에서 연합 아이덴티티와 관련된 개인정보 위험을 종합적으로 설명해 브라우저 중개 설계의 위험과 이점을 평가할 수 있도록 합니다.
7.1. 주체
이 섹션에서는 API 호출에 참여하는 네 명의 주체와 그 행동 기대를 설명합니다.
-
사용자 에이전트는 § 2 브라우저 API를 구현하며 RP 및 IDP 콘텐츠의 실행 컨텍스트를 제어합니다. 사용자 에이전트는 사용자가 신뢰하는 존재로 간주되며, RP와 IDP도 전이적으로 신뢰합니다.
-
RP는 사용자를 인증하거나 사용자 정보를 얻기 위해 FedCM API를 호출하는 웹사이트입니다. 모든 사이트가 API를 호출할 수 있으므로, RP가 수집하는 정보나 활용 방식에 대해 신뢰할 수 없습니다.
-
IDP는 FedCM 호출 대상으로 토큰을 발급하려는 제3자 사이트입니다. IDP는 일반적으로 RP보다 더 높은 신뢰를 가지며 이미 사용자의 개인정보를 보유하지만, IDP가 비승인 방식으로 정보를 활용할 가능성도 있습니다. 또한 API 호출에 명시된 IDP가 사용자가 모르는 IDP일 수도 있습니다. 이 경우에는 사전에 개인정보를 보유하지 않았을 가능성이 높습니다.
-
트래커는 IDP가 아니지만 FedCM API를 악용해 사용자를 여러 사이트에서 추적하려는 제3자 웹사이트입니다. 트래커는 RP에 의해 의도적 또는 비의도적으로 삽입될 수 있으며(예: RP가 동적으로 삽입하는 여러 스크립트 태그 중 하나로), 일반적으로 웹사이트 UI를 수정하지 않아 추적 여부를 감지하기 힘듭니다. 트래커가 여러 웹사이트에서 추적 스크립트를 성공적으로 추가하면, 이 정보를 다양한 목적으로 활용하거나 판매할 수 있습니다. FedCM API를 통한 웹 전체 추적은 트래커에게 허용되어서는 안 됩니다.
위 내용을 바탕으로 개인정보 논의의 전제는 다음과 같습니다:
-
RP, IDP, 트래커가 사용자의 허락 없이 특정 사용자가 특정 사이트를 방문했다는 사실을 알아내는 것은 허용되지 않습니다. 즉, 사용자 에이전트는 특정 사용자 신원이 특정 사이트를 방문한 사실을 RP, IDP, 트래커에게 숨겨야 합니다. 사용자가 허락하면 RP와 IDP에게 이 사실을 공유할 수 있습니다. 특히, RP는 사용자 신원을, IDP는 사용자가 방문한 사이트를 FedCM 플로우에서 사용자의 허락을 받기 전에는 알아서는 안 됩니다.
-
사용자 에이전트는 언제 사용자가 IDP가 RP와 통신해 사용자 신원을 제공하는 것을 허락했는지 판단할 책임이 있습니다.
-
사용자 에이전트가 사용자가 RP에 계정 정보를 제공하도록 허락했음을 판단하면, IDP와 RP가 해당 사용자 계정에 대한 정보를 알고 있어도 됩니다. RP는 다른 사용자 계정 정보를 알아서는 안 됩니다.
7.2. 네트워크 요청
이 명세는 FedCM fetch가 RP가 지정한 provider 기준으로 모두 동일 오리진임을 보장합니다. 그 이유는 쿠키를 사용하는 fetch가 지정된 오리진의 쿠키를 사용하므로, 임의의 오리진을 허용하면 쿠키가 누구와 공유되는지 혼란과 개인정보 문제가 생길 수 있기 때문입니다. 모든 fetch를 동일 오리진으로 유지하는 가장 쉬운 방법은 리다이렉트 금지와 fetch URL의 오리진 체크입니다.
-
설정 파일 fetch는 쿠키,
client_id
, referrer 없이 수행되므로 사용자 추적에 사용할 수 없습니다. 누구나 이 fetch를 수행할 수 있으며, 그 정보는 공개로 간주합니다. -
계정 엔드포인트 fetch는 IDP의 쿠키와 함께 수행되지만,
client_id
와 referrer 없이 수행되므로 사용자 추적에 사용할 수 없습니다. 이론적으로 RP가 새 권한을 얻는 셈이지만, IDP는 이미 DoS 방어를 기대받고 있습니다. 또한 사용자 에이전트는 한 페이지당 FedCM 플로우 1개만 허용하고, 추가 시 즉시 거부합니다. FedCM 플로우는 사용자 상호작용(또는 긴 타이머)로만 종료되므로 fetch 횟수는 문제되지 않습니다. IDP는 이 fetch로 사용자의 많은 정보를 얻지만, 자세한 내용은 아래에서 설명합니다. -
클라이언트 메타데이터 엔드포인트 fetch도 IDP의 쿠키 없이 수행되므로 사용자 추적에 사용할 수 없습니다. 대신
client_id
와 referrer를 포함합니다. 이를 통해 IDP가 사용자 에이전트에 개인정보처리방침·서비스약관을 전달할 수 있습니다. 타이밍 공격을 제외하면 RP가 얻는 것은 없고, RP는 원래도 이 fetch를 쿠키 없이 직접 할 수 있었습니다. -
토큰 fetch는 설계상 해당 사이트에서 사용자를 IDP에 노출시킵니다. 쿠키,
client_id
, referrer가 모두 포함됩니다. 따라서 반드시 사용자 에이전트 UI 상호작용이 필요하며, IDP가 RP에 연합 로그인/회원가입에 필요한 정보만 전달할 수 있습니다. RP나 IDP가 사용자 허락 없이 토큰 fetch를 강제할 수 없으며, 사용자 에이전트를 속이거나 우회할 수 없습니다. -
연결 해제 엔드포인트 fetch는 사용자가 해당 RP에서 FedCM 플로우를 한 번 이상 성공한 후에만 가능합니다. IDP에 credentialed 요청을 보내므로, 사용자 에이전트가 FedCM을 한 번 사용한 후에도 무제한 요청을 허용하면 안 됩니다. 그래서 연결 해제 시 credentialed 요청을 보낼 때마다 최소 한 계정이 connected accounts set에서 제거되어, RP가 IDP로 쿠키가 포함된 요청을 무한히 보낼 수 없게 합니다.
7.3. 공격 시나리오
이 섹션에서는 다양한 주체가 사용자 정보를 획득하려 시도할 수 있는 시나리오를 설명합니다. 다음과 같은 가능성을 고려합니다:
이 섹션에서는 주체가 위의 위협 중 하나를 실현하려는 목적을 가지고 직접 또는 간접적으로 행동을 수행하면 정보 수집에 참여하는 것으로 간주합니다.
참고: 간접적 공모의 예로 RP가 IDP가 제공한 스크립트를 import하는 경우, IDP가 사용자를 추적하려는 의도를 갖는 경우가 있습니다.
논의의 편의를 위해, 본 문서는 서드파티 쿠키가 기본적으로 비활성화되어 있고, 추적 메커니즘으로서 더이상 효과적이지 않으며, 링크 장식이나 postMessage를 통한 ‘바운스 트래킹’에 대한 일부 대응책이 구현되어 있다고 가정합니다. 대부분의 시나리오는 이러한 방식 없이 사용자 추적이 어떻게 일어날 수 있는지에 대해 다룹니다. 자세한 내용은 Pervasive Monitoring Is an Attack도 참고하세요.
7.3.1. 매니페스트 핑거프린팅
FedCM API에 이단계 매니페스트(see IdentityCredential 생성 알고리즘)가 없고, 단일 매니페스트만 있었다고 가정합니다. 이는 다음과 같은 핑거프린팅 공격을 유발할 수 있습니다:
// 아래 코드는 manifest JSON 파일을 fetch하며, 이 파일은 RP의 오리진을 알 수 있습니다 :( const cred= await navigator. credentials. get({ identity: { providers: [{ configURL: \`https://idp.example/ ${ window. location. href} \` }] } });
참고: 이 공격에 대한 설명은 여기에서 읽을 수 있습니다.
여기서 RP가 매니페스트를 IDP에서 fetch할 때 자신의 정보를 식별자와 함께 포함합니다. FedCM API가 수행하는 credentialed fetch와 결합되면 IDP가 사용자가 방문 중인 웹사이트를 사용자 허락 없이 추적할 수 있게 됩니다. 이에 대한 대응책은 § 3.1 웰노운 파일의 사용입니다. IDP 도메인 root에 파일이 존재하도록 강제해, 파일명이 방문 중인 RP에 대한 핑거프린트를 주지 않도록 합니다.
전체 매니페스트를 해당 위치에 둘 수도 있지만, 대신 실제 매니페스트를 그곳에서 가리키게 합니다. 이렇게 하면 만약 IDP가 미래에 여러 개의 매니페스트를 필요로 한다면 작은 고정 개수만 허용하는 등의 유연성이 생깁니다. 또한 매니페스트가 루트가 아닌 임의의 파일 위치에서 변경될 수 있게 하여, 도메인 루트의 파일만 변경해야 하는 제약을 완화합니다.
7.3.2. 타이밍 공격
타이밍 공격에서는 RP와 IDP가 공모하여, IDP가 (RP 오리진, IDP 사용자 신원) 쌍을 사용자 허락 없이 유추할 수 있도록 합니다. 이 공격은 결정적이지 않으며, 두 정보를 결합해야 하므로 통계적 오류가 있을 수 있습니다. 하지만 이 공격을 방지하고 경제적으로 실행이 어렵게 하는 것이 중요합니다. 이 공격에서는 네트워크 요청에 큰 핑거프린팅 요소(예: IP 주소)가 없다고 가정합니다. 이런 요소는 사용자 에이전트마다 다르며 완전히 제거하기 어렵지만, 일반적으로 사용자 에이전트가 점진적으로 개선할 것으로 기대됩니다. 네트워크 요청에 묶인 정보가 타이밍 공격을 쉽게 만들므로, 더 적극적으로 대응할 필요가 있습니다.
참고: 이 공격에 대한 설명과 논의는 여기에서 볼 수 있습니다.
공격 방식은 다음과 같습니다:
-
RP가 API 호출 시점(time A)을 기록하고, IDP에 전송해, RP의 클라이언트 메타데이터 fetch 도착 시점을 마킹해 스스로를 파악합니다. time A는 사이트에 연결됩니다.
-
인증된 요청이 IDP로 전송되는데, 명시적으로 RP를 식별하지는 않지만, 앞의 요청과 충분히 가까운 시점에 전송됩니다. IDP는 이 요청의 도착 시점(time B)을 기록합니다. time B는 사용자 신원에 연결됩니다.
-
IDP는 time A와 time B를 연관시켜 (사이트, 사용자 신원) 쌍을 높은 확률로 찾습니다. 핑거프린팅이 있으면 정확도가 더 높아질 수 있습니다.
이런 종류의 상관관계는 FedCM 없이도 크로스 오리진 top-level 네비게이션 사용으로 이미 가능하지만, FedCM을 이용하면 타이밍 해상도가 높아지거나 사용자가 알아차리기 어렵다면 문제가 더 심각해집니다(예: IDP가 사용자 에이전트에 빈 계정 목록을 반환해 브라우저 UI를 일부러 띄우지 않아 공격이 사용자에게 보이지 않게 만들 수 있음).
사용자 에이전트는 이 공격을 상호운용적으로 완화하여 사용자를 보호해야 합니다.
7.3.3. IDP 침해
Target Privacy Threat Model § hl-intrusion에서 인용
프라이버시 침해는 항상 사이트가 무언가를 학습하는 것에서 오는 것이 아닙니다.
RFC6973: Intrusion에서 인용
침해(Intrusion)는 개인의 삶이나 활동을 방해하거나 중단시키는 침입 행위를 의미합니다. 침해는 개인이 혼자 있고자 하는 욕망을 좌절시키거나, 시간·주의를 소모시키거나, 활동을 방해할 수 있습니다.
페더레이션 맥락에서, 침해는 RP와 IDP가 공모하여 사용자의 의도와 불균형적으로 로그인 권유를 과도하게 하는 경우 발생합니다. 원치 않는 알림처럼, RP는 IDP와 공모해 사용자를 과도하게 로그인시킬 수 있습니다.
사용자 에이전트는 사용자 제어를 중재하여 사용자의 의도나 관련 프라이버시 위험에 비례해 권한을 제시함으로써 이를 완화할 수 있습니다. 예를 들어, 사용자 에이전트는 사용자의 의도가 충분히 확실하다고 판단되면 눈에 띄고 방해가 되는 모달 다이얼로그를, 그렇지 않으면 조용하고 보수적인 UI 힌트를 제공할 수 있습니다.
사용자 에이전트는 위험에 따라 사용자의 경험 방해 정도를 제어할 수도 있습니다. 예를 들어, directed identifier가 교환될 때는 부작용 위험이 더 명확하므로 더 적극적인 사용자 경험을 제공하고, global identifier가 교환될 때는 더 보수적인 사용자 경험을 제공할 수 있습니다.
7.3.4. 사이트 간 상관관계
이 공격은 여러 RP가 서로 협력하여 사용자의 데이터를 상호 연관시키고 더 풍부한 프로필을 구축할 때 발생합니다. 사용자가 자신의 전체 이름, 이메일 주소, 전화번호 등 개인정보를 여러 RP에 자발적으로 제공하면, 이러한 RP들은 협력하여 해당 사용자의 프로필 및 여러 협력 사이트에서의 활동을 구축할 수 있습니다. 때때로 이런 현상을 ‘조인(join)’이라고 하는데, 이는 복수 RP의 계정 데이터베이스 사이에서 사용자 레코드를 결합하는 것과 같습니다. 이런 상관관계 및 프로필 구축은 사용자의 통제 밖이며, 사용자 에이전트나 IDP의 관점에서도 완전히 벗어나 있습니다.
-
사용자가 IDP로 RP1(보석을 판매함)에 로그인하면서 RP1에 이메일 주소 user@email.example을 제공합니다.
-
사용자가 IDP로 RP2(집을 판매함)에 로그인하면서 RP2에 이메일 주소 user@email.example을 제공합니다.
-
사용자가 RP1에서 웨딩링 컬렉션을 둘러봅니다.
-
RP1이 RP2에 user@email.example이 웨딩링을 쇼핑 중임을 비공식적으로 알립니다.
-
사용자가 RP2에서 주택 목록을 둘러봅니다.
-
RP2는 사용자가 RP1에서 웨딩링을 쇼핑 중인 사실을 활용해 광고를 하거나 주택 목록을 필터링합니다.
-
사용자는 RP2가 자신이 웨딩링을 쇼핑 중인 사실을 알고 있다는 점에 놀랍니다.
RP들이 백채널을 통해 사용자 데이터를 결합하는 문제는 식별 가능한 사용자 데이터의 확산에 내재된 문제입니다. 이는 각 IDP와 연결된 사용자의 신원을 효과적으로 식별할 수 있는 지향성(directed) 식별자를 발급함으로써 해결할 수 있습니다. 이러한 식별자는 고유하며 다른 RP와 상관관계를 맺을 수 없습니다. 과거에는 사용자의 이름, IDP, RP 등을 일방향 해시(one-way hash)로 처리해 이를 달성하는 방식이 있었습니다. 이런 식별자는 고유하므로 다른 RP와 상관관계를 맺을 수 없습니다.
7.3.5. 허가되지 않은 데이터 사용
또 다른 공격은 RP 또는 IDP가 사용자가 허락하지 않은 목적으로 사용자 정보를 활용하는 경우입니다. 사용자가 IDP가 RP에 정보를 제공하는 것에 동의할 때, 그 동의는 로그인 또는 개인화 같은 특정 목적에 한정됩니다. 예를 들어, RP가 사용자가 예상하지 못하고 허락하지 않은 다른 목적으로(예: 이메일 주소를 스팸 리스트에 판매) 데이터를 사용할 수 있습니다. 지향성 식별자를 사용하더라도 스팸 위험은 존재할 수 있습니다.
7.3.6. RP 핑거프린팅
이 공격은 RP가 클라이언트 상태 기반의 추적을 통해 사용자를 식별할 때 발생합니다. 웹에 어떠한 형태의 클라이언트 상태를 노출하는 API는 핑거프린팅 벡터가 될 위험이 있습니다. 이 API의 목적은 사용자가 RP에 신원을 제공하는 것이며, 사용자는 예를 들어 로그아웃 등의 방법으로 그 신원 접근을 철회할 수 있어야 합니다. 그러나 추적하는 RP는 이전에 로그인했던 사용자를 감지하기 위해 상태를 유지할 수 있습니다:
7.3.7. 2차적 이용
2차적 이용이란, 개인으로부터 수집한 정보를 그 정보가 수집된 목적과 다른 목적으로, 해당 개인의 동의 없이 사용하는 것을 말합니다. 이 공격은 IDP가 수집한 정보를 오용하여 로그인 이외의 다른 목적으로 활용할 때 발생합니다.
기존 페더레이션 프로토콜에서는 IDP가 토큰을 요청하는 서비스가 무엇인지 알아야 신원 페더레이션을 허용할 수 있습니다. 아이덴티티 제공자는 이 점을 활용해, 동일 계정으로 페더레이션을 이용한 사이트 전반에 걸친 사용자의 프로필을 구축할 수 있습니다. 예를 들어, 이렇게 구축된 프로필을 이용해, 해당 IDP가 관리하는 사이트를 브라우징하는 사용자에게 맞춤형 광고를 제공할 수도 있습니다.
이 위험은 IDP가 기존 사용자 계정 정보를 갖고 있지 않은 경우에도(예를 들어 진짜 IDP가 아닌 경우), FedCM 요청이 IDP로 credentialed 방식으로 전송되기 때문에 존재할 수 있습니다. 이러한 위험은 RP와 IDP가 § 7.3.2 타이밍 공격을 통해 추적을 가능하게 하도록 공모하는 경우에 더 발생하기 쉽습니다.
IDP가 사용자를 추적하는 것을 방지하는 것은 어렵습니다. RP는 토큰 재사용, 사기 및 오용 방지 같은 보안상의 이유로 반드시 identity 토큰에 명시되어야 합니다. IDP가 RP를 알지 못하도록 하면서도 토큰 재사용을 막는 암호학적 방식이 개발된 바 있습니다(예시: Mozilla의 personas). 이러한 방식은 본 명세에서는 채택되지 않았습니다.
8. 확장성
참고: 확장성 메커니즘을 살펴봅니다.
9. 감사의 글
참고: 감사의 글 섹션을 작성합니다.
10. FPWD 이슈
참고: WG에서는 아래 이슈들을 Candidate Recommendation 출판 전에 반드시 공식적으로 해결해야 할 중요한 오픈 이슈로 표시했습니다.- 이슈 240: 사용자가 RP가 나열한 IdP 외의 IdP를 사용할 수 없음
- 이슈 317: Accounts List에서 이메일에 대한 우려
- 이슈 319: 여러 개의 IDP 사용 허용
- 이슈 320: Sec-FedCM-CSRF와 Sec-Fetch-Mode의 차이
- 이슈 352: IDP와 성능 측정 정보 공유
- 이슈 407: [Context API] - Authz / scope 지정 기능과의 관계
- 이슈 428: Identity Assertions endpoint에 CORS 적용 강제
- 이슈 441: FedCM을 지원하기 위한 IDP의 추가 인프라 필요
- 이슈 442: 아직 로그인되지 않은 IDP는 이 플로우에서 성공 경로가 없음
- 이슈 467: FedCM 승인을 받은 후 Storage Access API를 통한 Cross-Site Cookie Access 사용 사례?
- 이슈 488: 사용자가 로그인 의사를 보여준 후 로그인 실패 시 혼란
- 이슈 511: 추가 계정에 로그인 허용
- 이슈 517: 사용자 에이전트가 "Connected Accounts Set"을 유연하게 사용할 수 있도록 허용
- 이슈 537: 동일 사이트 서브리소스에서 IDP 로그인 상태 설정 허용
- 이슈 552: IDP가 eTLD+1 내에서 여러 설정 파일 사용 허용
- 이슈 553: IDP가 서로 다른 컨텍스트에서 서로 다른 계정 목록 노출 허용
- 이슈 555: IdP가 팝업 창에서 요청을 계속하고 완료할 수 있도록 허용
- 이슈 556: ID assertion endpoint에 임의의 파라미터 전달 허용
- 이슈 559: RP가 사용자의 프로필 속성을 선택적으로 요청할 수 있도록 허용
- 이슈 578: IdP가 String이 아닌 JSON 객체를 RP에 반환 허용
- 이슈 585: IdP 등록 및 RP가 "type"으로 매칭 허용
- 이슈 587: 왜 SameSite=none이어야 하는가?
- 이슈 599: FedCM을 위한 OAuth 프로필
- 이슈 609: 명세에서 SameSite=Strict 쿠키를 전송한다고 명시
- 이슈 616:
params
가 명세에 병합되면nonce
파라미터 사용 중단 - 이슈 618: 추가 추적 완화 전 체인 인증 플로우 지원
- 이슈 620: 등록된 IdP의 eTLD+1에서 더 쉽게 배포 가능하게 하기
- 이슈 625: getUserInfo에서 returning accounts 먼저 반환
- 이슈 626: PP/TOS 요구사항이 자동 재인증과 다름
- 이슈 627: webdriver 명령으로 PP/TOS 열기 추가