RFC 9396 OAuth-RAR 2023년 5월
Lodderstedt 외 표준 트랙 [페이지]
스트림:
인터넷 엔지니어링 태스크 포스(IETF)
RFC:
9396
범주:
표준 트랙
발행:
ISSN:
2070-1721
저자:
T. Lodderstedt
yes.com
J. Richer
Bespoke Engineering
B. Campbell
Ping Identity

RFC 9396

OAuth 2.0 리치 권한 부여 요청

초록

이 문서는 OAuth 메시지에서 세분화된 권한 부여 데이터를 전달하는 데 사용되는 새로운 매개변수 authorization_details를 명세한다.

이 메모의 상태

이것은 인터넷 표준 트랙 문서이다.

이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산물이다. 이는 IETF 커뮤니티의 합의를 나타낸다. 공개 검토를 거쳤으며 인터넷 엔지니어링 운영 그룹(IESG)에 의해 발행이 승인되었다. 인터넷 표준에 대한 추가 정보는 RFC 7841의 섹션 2에서 확인할 수 있다.

이 문서의 현재 상태, 모든 정오표, 그리고 이에 대한 피드백 제공 방법에 관한 정보는 https://www.rfc-editor.org/info/rfc9396에서 얻을 수 있다.

목차

1. 소개

"OAuth 2.0 Authorization Framework" [RFC6749]는 OAuth 클라이언트가 액세스 토큰의 요청된 범위, 즉 제한된 기능을 지정할 수 있게 하는 scope 매개변수를 정의한다. 이 메커니즘은 정적 시나리오와 "리소스 소유자의 프로필에 대한 읽기 액세스를 달라"와 같은 거친 단위의 권한 부여 요청을 구현하기에는 충분하다. 그러나 "Merchant A에게 45유로 금액을 이체할 수 있게 해 달라" 또는 "디렉터리 A에 대한 읽기 액세스와 파일 X에 대한 쓰기 액세스를 달라"와 같은 세분화된 권한 부여 요구 사항을 지정하기에는 충분하지 않다.

이 명세는 클라이언트가 JSON [RFC8259] 데이터 구조의 표현력을 사용하여 세분화된 권한 부여 요구 사항을 지정할 수 있게 하는 새로운 매개변수 authorization_details를 도입한다.

예를 들어 신용 이체에 대한 권한 부여 요청(여러 오픈뱅킹 이니셔티브에서 "payment initiation"으로 지정됨)은 다음과 같은 JSON 객체를 사용하여 표현될 수 있다:

{
   "type": "payment_initiation",
   "locations": [
      "https://example.com/payments"
   ],
   "instructedAmount": {
      "currency": "EUR",
      "amount": "123.50"
   },
   "creditorName": "Merchant A",
   "creditorAccount": {
      "bic":"ABCIDEFFXXX",
      "iban": "DE02100100109307118603"
   },
   "remittanceInformationUnstructured": "Ref Number Merchant"
}
그림 1: 신용 이체를 위한 권한 부여 요청의 예

이 객체는 금액, 통화, 채권자와 같이 의도된 결제에 대한 상세 정보를 포함하며, 이는 사용자에게 알리고 동의를 얻기 위해 필요하다. 권한 부여 서버(AS)와 해당 리소스 서버(RS) (결제 개시 API 제공)는 함께 이 동의를 시행한다.

오픈뱅킹 및 전자 서명 영역의 새로운 사용 사례에서 발생하는 과제에 대한 포괄적인 논의는 [Transaction-Auth]를 참조한다.

사용자 정의 권한 부여 요청을 용이하게 하는 것에 더해, 이 명세는 서로 다른 API에서 사용할 수 있는 공통 데이터 타입 필드 집합도 도입한다.

1.1. 규약 및 용어

이 문서의 핵심 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 및 "OPTIONAL"은 여기에 보인 것처럼 모두 대문자로 나타나는 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 한다.

이 명세는 "The OAuth 2.0 Authorization Framework" [RFC6749]에서 정의한 "access token", "refresh token", "authorization server" (AS), "resource server" (RS), "authorization endpoint", "authorization request", "authorization response", "token endpoint", "grant type", "access token request", "access token response", 및 "client"라는 용어를 사용한다.

2. 요청 매개변수 "authorization_details"

요청 매개변수 authorization_details는 JSON 표기법으로 객체의 배열을 포함한다. 각 JSON 객체는 특정 유형의 리소스에 대한 권한 부여 요구 사항을 지정하는 데이터를 포함한다. 리소스의 유형 또는 액세스 요구 사항은 type 필드에 의해 결정되며, 이는 다음과 같이 정의된다:

type:
문자열로 된 권한 부여 세부 정보 타입의 식별자. type 필드의 값은 그것을 포함하는 객체의 허용 가능한 내용을 결정한다. 이 값은 AS의 맥락에서 설명된 API에 대해 고유하다. 이 필드는 REQUIRED이다.

authorization_details 배열은 동일한 type의 여러 항목을 포함할 MAY 있다.

그림 2는 위에 표시된 예제 데이터를 사용한 payment_initiation 타입의 authorization_details를 보여준다:

[
   {
      "type": "payment_initiation",
      "actions": [
         "initiate",
         "status",
         "cancel"
      ],
      "locations": [
         "https://example.com/payments"
      ],
      "instructedAmount": {
         "currency": "EUR",
         "amount": "123.50"
      },
      "creditorName": "Merchant A",
      "creditorAccount": {
         "iban": "DE02100100109307118603"
      },
      "remittanceInformationUnstructured": "Ref Number Merchant"
   }
]
그림 2: 신용 이체를 위한 "authorization_details"의 예

그림 3은 계정 정보에 대한 액세스와 결제 개시 권한을 요청하는 결합된 요청을 보여준다:

[
   {
      "type": "account_information",
      "actions": [
         "list_accounts",
         "read_balances",
         "read_transactions"
      ],
      "locations": [
         "https://example.com/accounts"
      ]
   },
   {
      "type": "payment_initiation",
      "actions": [
         "initiate",
         "status",
         "cancel"
      ],
      "locations": [
         "https://example.com/payments"
      ],
      "instructedAmount": {
         "currency": "EUR",
         "amount": "123.50"
      },
      "creditorName": "Merchant A",
      "creditorAccount": {
         "iban": "DE02100100109307118603"
      },
      "remittanceInformationUnstructured": "Ref Number Merchant"
   }
]
그림 3: 결합된 요청을 위한 "authorization_details"의 예

account_informationpayment_initiationtype 필드를 가진 JSON 객체는 AS가 동의를 요청하는 데 사용할 서로 다른 authorization_details를 나타낸다.

2.1. 권한 부여 세부 정보 타입

AS는 type 매개변수 값의 해석뿐 아니라 type 매개변수가 허용하는 객체 필드를 제어한다. 그러나 type 매개변수의 값은 일반적으로 문서화되며 개발자가 사용하도록 의도된다. API 설계자는 모호함 없이 쉽게 복사할 수 있는 type 값을 선택하는 것이 RECOMMENDED된다. 예를 들어 일부 글리프는 동일한 시각적 문자를 나타내는 여러 Unicode 코드 포인트를 가지며, 개발자는 AS가 정의한 문자와 다른 문자를 입력할 가능성이 있다. 잠재적 혼동을 줄이는 가능한 방법에는 값을 ASCII [RFC0020] 문자로 제한하거나, 데이터 타입 값의 기계 판독 가능 목록을 제공하거나, 개발자에게 문서에서 직접 복사하여 붙여넣도록 지시하는 것이 포함된다.

애플리케이션 또는 API가 오픈 표준의 경우처럼 서로 다른 서버에 걸쳐 배포될 것으로 예상되는 경우, API 설계자는 자신이 제어하는 URI와 같이 자신의 제어하에 있는 충돌 방지 네임스페이스를 사용하는 것이 RECOMMENDED된다.

다음 예제는 구현이 https://scheme.example.org/ 네임스페이스를 활용하여 충돌 방지 타입 값을 보장할 수 있는 방법을 보여준다.

{
   "type": "https://scheme.example.org/files",
   "locations": [
      "https://example.com/files"
   ],
   "permissions": [
      {
         "path": "/myfiles/A",
         "access": [
            "read"
         ]
      },
      {
         "path": "/myfiles/A/X",
         "access": [
            "read",
            "write"
         ]
      }
   ]
}
그림 4: 타입 식별자로 URL을 사용하는 "authorization_details"의 예

2.2. 공통 데이터 필드

이 명세는 서로 다른 타입의 API 전반에서 사용할 수 있도록 설계된 공통 데이터 필드 집합을 정의한다. 이 명세는 API 정의가 이러한 공통 필드를 사용하도록 요구하지 않으며, 대신 API 설계자가 활용할 수 있는 재사용 가능한 일반 구성 요소로 제공한다. 모든 필드의 허용 가능한 값은 특정 "type" 값으로 정의되는 보호 대상 API에 의해 결정된다.

locations:
리소스 또는 RS의 위치를 나타내는 문자열 배열. 이러한 문자열은 일반적으로 RS의 위치를 식별하는 URI이다. 이 필드는 섹션 12에서 논의한 것처럼 클라이언트가 특정 RS를 지정할 수 있게 한다.
actions:
리소스에서 수행될 동작의 종류를 나타내는 문자열 배열.
datatypes:
리소스에서 요청되는 데이터의 종류를 나타내는 문자열 배열.
identifier:
API에서 사용할 수 있는 특정 리소스를 나타내는 문자열 식별자.
privileges:
리소스에서 요청되는 권한의 타입 또는 수준을 나타내는 문자열 배열.

서로 다른 공통 데이터 필드가 조합되어 사용될 때, 클라이언트가 요청하는 권한은 모든 값의 곱이다. 객체는 객체 내에 나열된 모든 actions 값을 객체 내에 나열된 모든 locations 값에서 객체 내에 나열된 모든 datatypes 값에 대해 사용하는 요청을 나타낸다. 다음 예에서 클라이언트는 customer_information API의 고객에 속한 contactsphotos 모두에 대해 readwrite 액세스를 요청하고 있다. 이 요청이 승인되면 클라이언트는 API가 정의한 권한의 어떤 조합도 사용할 수 있다고 가정할 것이다. 예를 들어 사진에 대한 읽기 액세스와 연락처에 대한 쓰기 액세스가 이에 해당한다.

[
   {
      "type": "customer_information",
      "locations": [
         "https://example.com/customers"
      ],
      "actions": [
         "read",
         "write"
      ],
      "datatypes": [
         "contacts",
         "photos"
      ]
   }
]
그림 5: 공통 데이터 필드가 있는 "authorization_details"의 예

클라이언트가 액세스를 더 세밀하게 제어하려는 경우 여러 객체를 보낼 수 있다. 이 예에서 클라이언트는 동일한 API 엔드포인트의 contacts에 대한 read 액세스와 photos에 대한 write 액세스를 요청하고 있다. 이 요청이 승인되면 클라이언트는 연락처에 쓸 수 없다.

[
   {
      "type": "customer_information",
      "locations": [
         "https://example.com/customers"
      ],
      "actions": [
         "read"
      ],
      "datatypes": [
         "contacts"
      ]
   },
   {
      "type": "customer_information",
      "locations": [
         "https://example.com/customers"
      ],
      "actions": [
         "write"
      ],
      "datatypes": [
         "photos"
      ]
   }
]
그림 6: 여러 객체에 공통 데이터 필드가 있는 "authorization_details"의 예

API는 각각의 권한 부여 객체의 type에 따라 자체 확장을 정의할 MAY 있다. API 설계자는 이 명세에서 정의한 공통 데이터 필드와 API 자체에 특화된 필드를 조합하여 사용할 것으로 예상된다. 다음 비규범적 예제는 두 개의 서로 다른 가상의 API type 값의 일부로 공통 필드와 API별 필드를 모두 사용하는 것을 보여준다. 첫 번째 액세스 요청은 여기에 지정된 actions, locations, 및 datatypes 필드와 함께 API별 geolocation 필드를 포함하며, 이는 주어진 좌표에서 촬영된 사진에 대한 액세스를 나타낸다. 두 번째 액세스 요청은 여기에 지정된 actionsidentifier 필드와 함께 API별 currency 필드를 포함한다.

[
   {
      "type":"photo-api",
      "actions":[
         "read",
         "write"
      ],
      "locations":[
         "https://server.example.net/",
         "https://resource.local/other"
      ],
      "datatypes":[
         "metadata",
         "images"
      ],
      "geolocation":[
         {
            "lat":-32.364,
            "lng":153.207
         },
         {
            "lat":-35.364,
            "lng":158.207
         }
      ]
   },
   {
      "type":"financial-transaction",
      "actions":[
         "withdraw"
      ],
      "identifier":"account-14-32-32-3",
      "currency":"USD"
   }
]
그림 7: 공통 및 확장 데이터 필드를 사용하는 "authorization_details"의 예

이 요청이 승인되면, 결과 액세스 토큰의 액세스 권한은 위와 마찬가지로 두 API 각각에 대해 요청된 액세스 타입의 합집합이 된다.

3. 권한 부여 요청

authorization_details 권한 부여 요청 매개변수는 scope 매개변수가 동일한 목적으로 사용되는 모든 위치에서 권한 부여 요구 사항을 지정하는 데 사용될 수 있으며, 예에는 다음이 포함된다:

[RFC6749]에 정의된 권한 부여 요청의 경우, 구현자는 흐름의 보안, 프라이버시 및 신뢰성을 개선하기 위해 pushed authorization requests [RFC9126] 사용을 고려할 MAY 있다. 자세한 내용은 섹션 12, 13, 및 11.4를 참조한다.

매개변수 인코딩은 각각의 맥락에 의해 결정된다. [RFC6749]에 따른 권한 부여 요청의 맥락에서, 매개변수는 섹션 2의 예제를 사용하여 그림 8에 보인 것처럼 직렬화된 JSON의 application/x-www-form-urlencoded 형식을 사용하여 인코딩된다 (줄바꿈은 표시 목적으로만 사용됨):

GET /authorize?response_type=code
   &client_id=s6BhdRkqt3
   &state=af0ifjsldkj
   &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
   &code_challenge_method=S256
   &code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bwc-uCHaoeK1t8U
   &authorization_details=%5B%7B%22type%22%3A%22account%5Finfo
   rmation%22%2C%22actions%22%3A%5B%22list%5Faccounts%22%2C%22
   read%5Fbalances%22%2C%22read%5Ftransactions%22%5D%2C%22loca
   tions%22%3A%5B%22https%3A%2F%2Fexample%2Ecom%2Faccounts%22%
   5D%7D%2C%7B%22type%22%3A%22payment%5Finitiation%22%2C%22act
   ions%22%3A%5B%22initiate%22%2C%22status%22%2C%22cancel%22%5
   D%2C%22locations%22%3A%5B%22https%3A%2F%2Fexample%2Ecom%2Fp
   ayments%22%5D%2C%22instructedAmount%22%3A%7B%22currency%22%
   3A%22EUR%22%2C%22amount%22%3A%22123%2E50%22%7D%2C%22credito
   rName%22%3A%22Merchant%20A%22%2C%22creditorAccount%22%3A%7B
   %22iban%22%3A%22DE02100100109307118603%22%7D%2C%22remittanc
   eInformationUnstructured%22%3A%22Ref%20Number%20Merchant%22
   %7D%5D HTTP/1.1
Host: server.example.com
그림 8: "authorization_details"가 포함된 권한 부여 요청의 예

authorization_details 매개변수에 제공된 데이터에 기반하여, AS는 요청된 액세스 권한에 대한 동의를 사용자에게 요청한다.

그림 9에서 클라이언트는 계정 정보에 대한 액세스와 결제 개시를 원한다:

[
   {
      "type": "account_information",
      "actions": [
         "list_accounts",
         "read_balances",
         "read_transactions"
      ],
      "locations": [
         "https://example.com/accounts"
      ]
   },
   {
      "type": "payment_initiation",
      "actions": [
         "initiate",
         "status",
         "cancel"
      ],
      "locations": [
         "https://example.com/payments"
      ],
      "instructedAmount": {
         "currency": "EUR",
         "amount": "123.50"
      },
      "creditorName": "Merchant A",
      "creditorAccount": {
         "iban": "DE02100100109307118603"
      },
      "remittanceInformationUnstructured": "Ref Number Merchant"
   }
]
그림 9: URL 디코딩된 "authorization_details"

3.1. "scope" 매개변수와의 관계

authorization_detailsscope는 독립적인 권한 부여 요구 사항을 전달하기 위해 동일한 권한 부여 요청에서 사용될 수 있다.

authorization_detailsscope의 결합 사용은 기존 OAuth 기반 애플리케이션이 authorization_details만 사용하는 방향으로 점진적으로 마이그레이션할 수 있도록 하기 위해 이 명세에서 부분적으로 지원된다. 주어진 API는 요구 사항 지정 형식 중 하나만 사용하는 것이 RECOMMENDED된다.

AS는 주어진 권한 부여 요청에 대해 두 요구 사항 집합을 서로 결합하여 처리해야 MUST 한다. AS가 이러한 매개변수를 결합하는 방법의 세부 사항은 보호 대상 API에 따라 다르며 이 명세의 범위를 벗어난다.

사용자 동의를 수집할 때, AS는 권한 부여 요청이 나타내는 병합된 요구 사항 집합을 제시해야 MUST 한다.

리소스 소유자가 클라이언트에게 요청된 액세스를 승인하면, AS는 해당 authorization_details(및 해당되는 경우 scope 값)와 연결된 토큰을 클라이언트에게 발급한다.

3.2. "resource" 매개변수와의 관계

[RFC8707]에 정의된 resource 권한 부여 요청 매개변수는 요청된 scope가 적용될 수 있는 리소스를 추가로 결정하는 데 사용될 수 있다. resource 매개변수는 AS가 authorization_details 권한 부여 요청 매개변수를 처리하는 방식에 아무런 영향을 주지 않는다.

4. 권한 부여 응답

이 명세는 권한 부여 응답에 대한 확장을 정의하지 않는다.

5. 권한 부여 오류 응답

AS는 알 수 없는 권한 부여 세부 정보 타입 또는 각각의 타입 정의를 준수하지 않는 권한 부여 세부 정보의 처리를 거부해야 MUST 한다. AS는 authorization_details 구조의 객체에 대해 다음 중 하나라도 참이면 처리를 중단하고 invalid_authorization_details 오류로 클라이언트에 응답해야 MUST 한다:

6. 토큰 요청

authorization_details 토큰 요청 매개변수는 클라이언트가 AS에 액세스 토큰에 할당하도록 요청하는 권한 부여 세부 정보를 지정하는 데 사용될 수 있다. AS는 기본 grant(authorization_code, refresh_token 등의 grant type의 경우) 또는 클라이언트의 정책(client_credentials grant type의 경우)이 요청된 권한 부여 세부 정보를 가진 액세스 토큰 발급을 허용하는지 확인한다. 그렇지 않으면 AS는 invalid_authorization_details 오류 코드(invalid_scope와 유사)로 요청을 거부한다.

6.1. 권한 부여 세부 정보 비교

OAuth 프로토콜의 많은 동작은 AS 및 RS가 요청이 이전의 기존 요청보다 "더 많은" 것을 요청하는지 또는 "더 적은" 것을 요청하는지에 기반하여 보안 결정을 내릴 수 있게 한다. 예를 들어 토큰을 갱신할 때 클라이언트는 리소스 소유자가 이전에 권한을 부여한 것보다 "더 적은 권한"을 가진 새 액세스 토큰을 요청할 수 있다. 요청된 액세스 토큰은 축소된 권한을 전달하지만, 그러한 요청으로 인해 리소스 소유자의 이전 권한 부여가 변경되지는 않는다. authorization_details의 필드 의미는 특정 API 또는 API 집합에 대한 구현별 사항이므로, 임의의 두 권한 부여 세부 정보 요청을 비교하는 표준화된 메커니즘은 없다. AS는 대부분의 경우 단순한 객체 비교에 의존해서는 안 된다. 일부 필드의 교집합이 API가 설계되고 배포된 방식에 따라 부여되는 액세스 권한에 부작용을 가질 수 있기 때문이다. 이는 일부 API에서 scope 값이 사용될 때와 유사한 효과이다.

새 요청을 기존 요청과 비교할 때, AS는 리소스 소유자가 해당 요청에 권한을 부여할 필요가 있는지 결정하기 위해 처음 요청을 승인할 때 사용한 것과 동일한 처리 기법을 사용할 수 있다. 이 비교의 세부 사항은 권한 부여 요청의 type 정의에 의존하며 이 명세의 범위를 벗어나지만, 공통 패턴을 적용할 수 있다.

이는 진행 중인 예제를 사용하여 설명한다. 섹션 3의 예제 권한 부여 요청이 사용자에 의해 승인되면, 다음 권한과 연결된 권한 부여 코드가 발급된다:

  • 계정 목록 조회,
  • 하나 이상의 계정 잔액에 대한 액세스,
  • 하나 이상의 계정 거래 내역에 대한 액세스, 및
  • 결제를 개시하고, 상태를 확인하며, 취소하는 것.

이제 클라이언트는 다음과 같이 계정 목록에만 액세스하는 권한이 할당된 액세스 토큰을 발급해 달라고 AS에 요청할 수 있다:

[
   {
      "type": "account_information",
      "actions": [
         "list_accounts"
      ],
      "locations": [
         "https://example.com/accounts"
      ]
   }
]
그림 10: 축소된 권한의 "authorization_details" 예

예제 API는 account_information 타입에서 사용하는 각 필드가 추가적 권리를 포함하도록 설계되어 있으며, actionslocations 배열 내의 각 값은 서로 다른 액세스 요소를 지정한다. 이 경우 비교를 수행하기 위해 AS는 다음 단계를 수행한다:

  • 이전 단계에서 발급된 권한 부여 코드가 account_information 타입의 권한 부여 세부 정보 객체를 포함하는지 확인한다,
  • 승인된 동작 목록에 list_accounts가 포함되어 있는지 확인한다, 그리고
  • locations 값이 이전에 승인된 위치만 포함하는지 확인한다.

모든 검사가 성공하면, AS는 축소된 액세스 집합을 가진 요청된 액세스 토큰을 발급한다.

이 비교는 이 특정 API 타입 정의와 관련이 있다는 점에 유의한다. 다른 API 타입 정의는 다른 처리 규칙을 가질 수 있다. 예를 들어 actions 값은 다른 actions 값과 관련된 권리를 포함할 수 있다. 예를 들어 클라이언트가 처음에 write 액세스를 가진 토큰을 요청하면, 이는 이 API에 대한 읽기 및 쓰기 액세스를 모두 의미한다:

[
    {
        "type": "example_api",
        "actions": [
            "write"
        ]
    }
]
그림 11: API에 대한 "write" 액세스를 요청하는 "authorization_details"의 예

나중에 동일한 클라이언트가 read 액세스를 위한 갱신 요청을 수행한다:

[
    {
        "type": "example_api",
        "actions": [
            "read"
        ]
    }
]
그림 12: API에 대한 "read" 액세스를 요청하는 "authorization_details"의 예

AS는 type 값과 actions 값을 비교하여 read 액세스가 클라이언트에게 이전에 부여된 write 액세스로 이미 포함되는지 결정한다.

동일한 API는 privileges의 가능한 값으로 admin을 사용하도록 설계될 수 있으며, 이 예에서는 결과 토큰이 리소스에서 모든 기능을 수행할 수 있음을 나타내는 데 사용된다. 그런 다음 해당 클라이언트가 API에 대한 이러한 admin 권한을 부여받으면, authorization_details는 다음과 같다:

[
    {
        "type": "example_api",
        "privileges": [
            "admin"
        ]
    }
]
그림 13: API에 대한 "admin" 액세스를 가진 "authorization_details"의 예

AS는 type 값을 비교하고, privileges 값이 이전에 클라이언트에게 부여된 read 또는 write 액세스의 어떤 측면도 포함한다고 판단한다. 다른 API 정의에서는 privileges를 값들이 서로 포함하지 않는 방식으로 사용할 수 있음에 유의한다.

다음 예제는 클라이언트가 공통 데이터 요소 locations(섹션 2.2 참조)를 사용하여 특정 RS로 제한된 액세스 토큰의 발급을 요청하는 방법을 보여준다. 진행 중인 예에서 클라이언트는 https://example.com/payments에 위치한 RS에 적용 가능한 payment_initiation 타입의 승인된 grant의 모든 권한을 다음과 같이 요청할 수 있다:

[
   {
      "type": "payment_initiation",
      "locations": [
         "https://example.com/payments"
      ]
   }
]

그림 14: 대상 제한 액세스 토큰을 요청하는 "authorization_details"의 예

7. 토큰 응답

[RFC6749]에 정의된 토큰 응답 매개변수에 더해, AS는 리소스 소유자가 승인하고 각각의 액세스 토큰에 할당한 authorization_details도 반환해야 MUST 한다.

토큰 응답에서 발급된 액세스 토큰에 할당되는 권한 부여 세부 정보는 해당 토큰 요청의 authorization_details 매개변수에 의해 결정된다. 클라이언트가 authorization_details 토큰 요청 매개변수를 지정하지 않으면, AS는 재량에 따라 결과 authorization_details를 결정한다.

AS는 클라이언트에 대한 authorization_details에서 값을 생략할 MAY 있다.

진행 중인 예에서는 다음과 같이 보인다:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
   "access_token": "2YotnFZFEjr1zCsicMWpAA",
   "token_type": "example",
   "expires_in": 3600,
   "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
   "authorization_details": [
      {
         "type": "payment_initiation",
         "actions": [
            "initiate",
            "status",
            "cancel"
         ],
         "locations": [
            "https://example.com/payments"
         ],
         "instructedAmount": {
            "currency": "EUR",
            "amount": "123.50"
         },
         "creditorName": "Merchant A",
         "creditorAccount": {
            "iban": "DE02100100109307118603"
         },
         "remittanceInformationUnstructured": "Ref Number Merchant"
      }
   ]
}
그림 15: 토큰 응답 예제

7.1. 토큰 응답의 보강된 권한 부여 세부 정보

액세스 토큰에 첨부된 권한 부여 세부 정보는 클라이언트가 요청한 것과 다를 MAY 있다. 사용자가 클라이언트가 요청한 것보다 적게 권한을 부여하는 것 외에도, AS가 권한 부여 세부 정보 객체의 데이터를 보강하는 사용 사례가 있다. 보강이 허용되는지와 그것이 어떻게 동작하는지의 구체적인 사항은 필연적으로 각각의 권한 부여 세부 정보 타입 정의의 일부이다.

한 예로, 클라이언트가 계정 정보에 대한 액세스를 요청하지만 액세스할 수 있는 특정 계정에 대한 결정은 사용자에게 맡길 수 있다. 권한 부여 과정 중 사용자는 클라이언트가 액세스하도록 허용하려는 자신의 계정 하위 집합을 선택한다. 선택된 계정을 전달하는 하나의 설계 옵션으로, AS는 이 정보를 해당 권한 부여 세부 정보 객체에 추가할 수 있다.

그 예에서 요청된 authorization_details 매개변수는 다음과 같이 보일 수 있다. 이 예에서 빈 배열은 AS에 의해 보강 중 데이터가 추가될 위치를 위한 자리 표시자 역할을 한다. 이 예는 설명용일 뿐이며, 어떤 권한 부여 세부 정보 타입의 구체적인 설계를 이 방식으로 하는 것을 선호한다는 의미는 아니다.

"authorization_details": [
   {
      "type": "account_information",
      "access": {
         "accounts": [],
         "balances": [],
         "transactions": []
      },
      "recurringIndicator":true
   }
]
그림 16: 요청된 "authorization_details"의 예

그런 다음 AS는 권한 부여 세부 정보 객체를 확장하고 해당 계정 식별자를 추가한다.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JokF0XG5Qx2TlKWIA",
   "authorization_details":[
      {
         "type":"account_information",
         "access":{
            "accounts":[
               {
                  "iban":"DE2310010010123456789"
               },
               {
                  "maskedPan":"123456xxxxxx1234"
               }
            ],
            "balances":[
               {
                  "iban":"DE2310010010123456789"
               }
            ],
            "transactions":[
               {
                  "iban":"DE2310010010123456789"
               },
               {
                  "maskedPan":"123456xxxxxx1234"
               }
            ]
         },
         "recurringIndicator":true
      }
   ]
}
그림 17: 보강된 "authorization_details"의 예

또 다른 예로, 클라이언트가 의료 기록에 대한 액세스를 요청하지만 요청 시점에는 기록 번호를 모른다고 하자. 이 예에서 클라이언트는 원하는 액세스 타입을 지정하지만 해당 액세스의 위치나 식별자는 지정하지 않는다.

{
"authorization_details": [
   {
      "type": "medical_record",
      "sens": [ "HIV", "ETH", "MART" ],
      "actions": [ "read" ],
      "datatypes": [ "Patient", "Observation", "Appointment" ]
   }
]}
그림 18: 요청된 "authorization_details"의 예

사용자가 AS와 상호작용할 때, 사용자는 클라이언트에 제공할 책임이 있는 의료 기록을 선택한다. 이 정보는 액세스 토큰과 함께 반환된다.

{
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JokF0XG5Qx2TlKWIA",
   "authorization_details":[
    {
      "type": "medical_record",
      "sens": [ "HIV", "ETH", "MART" ],
      "actions": [ "read" ],
      "datatypes": [ "Patient", "Observation", "Appointment" ],
      "identifier": "patient-541235",
      "locations": [ "https://records.example.com/" ]
     }
  ]
}
그림 19: 보강된 "authorization_details"의 예

8. 토큰 오류 응답

토큰 오류 응답은 섹션 5에 주어진 규칙을 준수해야 MUST 한다.

9. 리소스 서버

RS가 권한 부여 과정에서 승인된 권한 부여 세부 정보를 시행할 수 있도록 하기 위해, AS는 이 데이터를 RS가 사용할 수 있게 해야 MUST 한다. AS는 JSON Web Token (JWT) 형식의 액세스 토큰 또는 토큰 인트로스펙션 응답에 authorization_details 필드를 추가할 MAY 있다.

9.1. JWT 기반 액세스 토큰

액세스 토큰이 JWT [RFC7519]인 경우, AS는 특정 audience에 맞게 필터링된 권한 부여 세부 정보 객체를 최상위 클레임으로 추가하는 것이 RECOMMENDED된다.

AS는 일반적으로 RS가 요청 처리를 위해 필요로 하는 추가 클레임도 JWT에 추가한다. 예를 들어 사용자 ID, 역할, 거래별 데이터가 있다. 특정 RS가 필요로 하는 클레임은 AS와의 RS별 정책에 의해 정의된다.

다음은 위의 결제 개시 예제에 대한 예제 JWT의 내용을 보여준다:

{
   "iss": "https://as.example.com",
   "sub": "24400320",
   "aud": "a7AfcPcsl2",
   "exp": 1311281970,
   "acr": "psd2_sca",
   "txn": "8b4729cc-32e4-4370-8cf0-5796154d1296",
   "authorization_details": [
      {
         "type": "https://scheme.example.com/payment_initiation",
         "actions": [
            "initiate",
            "status",
            "cancel"
         ],
         "locations": [
            "https://example.com/payments"
         ],
         "instructedAmount": {
            "currency": "EUR",
            "amount": "123.50"
         },
         "creditorName": "Merchant A",
         "creditorAccount": {
            "iban": "DE02100100109307118603"
         },
         "remittanceInformationUnstructured": "Ref Number Merchant"
      }
   ],
   "debtorAccount": {
      "iban": "DE40100100103307118608",
      "user_role": "owner"
   }
}
그림 20: JWT 기반 액세스 토큰의 "authorization_details" 예

이 경우 AS는 JWT 기반 액세스 토큰에 다음 예제 클레임을 추가했다:

sub:
클라이언트가 결제 개시를 요청하는 사용자를 나타낸다.
txn:
제공자 example.com의 서비스 전반에서 거래를 추적하는 데 사용되는 거래 ID
debtorAccount:
채무자 계정을 포함하는 API별 필드. 예에서 이 계정은 authorization_details에 전달되지 않았지만 권한 부여 과정에서 사용자가 선택했다. user_role 필드는 이 특정 계정과 관련하여 사용자가 가진 역할을 전달한다. 이 경우 사용자는 소유자이다. 이 데이터는 결제 API(RS)에서 액세스 제어에 사용된다.

9.2. 토큰 인트로스펙션

토큰 인트로스펙션 [RFC7662]은 RS가 액세스 토큰에 대한 정보를 확인하기 위해 AS에 질의할 수 있는 수단을 제공한다. AS가 토큰에 대한 권한 부여 세부 정보 정보를 응답에 포함하는 경우, 이 정보는 인트로스펙션 응답 JSON 객체의 최상위 멤버인 authorization_details로 전달되어야 MUST 한다. authorization_details 멤버는 섹션 2에 정의된 것과 동일한 구조를 포함해야 MUST 하며, 인트로스펙션 요청을 수행하는 RS에 맞게 필터링되고 확장될 수 있다.

다음은 결제 개시 예제에 대한 인트로스펙션 응답 예이다:

{
   "active": true,
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "exp": 1311281970,
   "acr": "psd2_sca",
   "txn": "8b4729cc-32e4-4370-8cf0-5796154d1296",
   "authorization_details": [
      {
         "type": "https://scheme.example.com/payment_initiation",
         "actions": [
            "initiate",
            "status",
            "cancel"
         ],
         "locations": [
            "https://example.com/payments"
         ],
         "instructedAmount": {
            "currency": "EUR",
            "amount": "123.50"
         },
         "creditorName": "Merchant123",
         "creditorAccount": {
            "iban": "DE02100100109307118603"
         },
         "remittanceInformationUnstructured": "Ref Number Merchant"
      }
   ],
   "debtorAccount": {
      "iban": "DE40100100103307118608",
      "user_role": "owner"
   }
}
그림 21: 인트로스펙션 응답의 "authorization_details" 예

10. 메타데이터

이 기능에 대한 지원을 알리기 위해, 지원되는 권한 부여 세부 정보 타입 목록은 [RFC8414]의 AS 메타데이터 응답에 JSON 배열인 메타데이터 매개변수 authorization_details_types_supported를 사용하여 포함된다.

이는 다음 예제로 설명된다:

{
   ...
   "authorization_details_types_supported":[
      "payment_initiation",
      "account_information"
   ]
}
그림 22: 지원되는 권한 부여 세부 정보에 대한 서버 메타데이터의 예

클라이언트는 권한 부여를 요청할 때 사용할 권한 부여 세부 정보 타입을 JSON 배열인 클라이언트 등록 메타데이터 매개변수 authorization_details_types로 나타낼 MAY 있다.

이는 다음 예제로 설명된다:

{
   ...
   "authorization_details_types":[
      "payment_initiation"
   ]
}
그림 23: 권한 부여 세부 정보에 대한 서버 메타데이터의 예

AS에 권한 부여 세부 정보 타입을 등록하는 것은 이 명세의 범위를 벗어난다.

11. 구현 고려 사항

11.1. 특정 배포에서 권한 부여 세부 정보 사용

특정 배포에서 권한 부여 세부 정보를 사용하려면 다음 단계가 필요하다:

  • 권한 부여 세부 정보 타입을 정의한다.
  • OAuth 서버 메타데이터에 권한 부여 세부 정보 타입을 게시한다.
  • 사용자 동의 프롬프트에서 권한 부여 세부 정보를 어떻게 표시할지 결정한다.
  • 필요한 경우, 사용자 동의 과정에서 권한 부여 세부 정보를 보강한다(예: 선택된 계정을 추가하거나 만료를 설정).
  • 필요한 경우, 권한 부여 세부 정보가 액세스 토큰 내용 또는 인트로스펙션 응답에 어떻게 반영되는지 결정한다.
  • RS가 권한 부여 세부 정보 또는 권한 부여 세부 정보에서 파생된 토큰 데이터를 어떻게 처리할지 결정한다.
  • 필요한 경우, 클라이언트가 특정 권한 부여 세부 정보 타입을 사용할 수 있도록 권한을 부여한다.

11.2. 최소 구현 지원

이 명세를 지원하는 일반적인 AS 구현은 다음 기본 기능을 제공해야 한다:

  • OAuth 서버 메타데이터에서 지원되는 권한 부여 세부 정보 타입의 광고 지원
  • 이 명세를 준수하여 권한 부여 요청에서 authorization_details 매개변수 수락
  • 동의된 권한 부여 세부 정보를 grant의 일부로 저장 지원
  • 권한 부여 세부 정보를 RS가 사용할 수 있도록 액세스 토큰 및 토큰 인트로스펙션 응답에 추가하는 기본 동작 구현(scope 값과 유사). 이는 모든 grant type, 특히 authorization_coderefresh_token에서 동작해야 한다.

권한 부여 세부 정보의 처리 및 표시는 서로 다른 권한 부여 세부 정보 타입 간에 크게 달라질 것이다. 따라서 구현은 해당 동작의 사용자 정의를 지원해야 한다. 특히 구현은 배포가 다음을 수행할 수 있게 해야 한다:

  • 권한 부여 세부 정보의 표시 방식을 결정한다;
  • 사용자 동의 과정에서 요청된 권한 부여 세부 정보를 수정한다. 예를 들어 필드를 추가한다; 그리고
  • 요청된 권한 부여 세부 정보와 기존 권한 부여 세부 정보를 병합한다.

이러한 사용자 정의를 지원하는 한 가지 접근 방식은 확장 모듈 등록을 허용하는 메커니즘을 두는 것이다. 각 확장 모듈은 각각의 사용자 동의를 렌더링하고 구조화된 액세스 토큰 또는 토큰 인트로스펙션 응답을 통해 RS에 필요한 데이터를 제공하기 위해 필요한 변환을 담당한다.

11.3. 기계 판독 가능 타입 스키마 사용

구현은 배포가 권한 부여 세부 정보 타입을 정의하기 위해 기계 판독 가능 스키마 언어를 사용하도록 허용할 수 있으며, 이를 통해 이러한 스키마에 대해 권한 부여 세부 정보 객체를 생성하고 검증하는 것을 용이하게 할 수 있다. 예를 들어 권한 부여 세부 정보 type이 JSON Schemas [JSON.Schema]를 사용하여 정의된 경우, JSON Schema 식별자를 각각의 권한 부여 세부 정보 객체에서 type 값으로 사용할 수 있다.

그러나 type 값은 AS 및 필요한 범위 내에서 클라이언트와 RS가 이해하는 식별자라는 점에 유의한다. 이 명세는 type 값이 기계 판독 가능 스키마 형식을 가리킨다거나, 시스템의 어떤 당사자(클라이언트, AS, RS 등)가 type 필드의 내용을 특정한 방식으로 역참조하거나 처리한다고 가정하지 않는다.

11.4. 큰 요청

요청 매개변수 또는 요청 객체에 authorization_details를 포함하는 권한 부여 요청 URI는 매우 길어질 수 있다. 따라서 구현자는 authorization_details를 신뢰할 수 있고 안전한 방식으로 전달하기 위해 [RFC9126]에 정의된 pushed request object 메커니즘과 함께 [RFC9101]에 정의된 request_uri 매개변수 사용을 고려해야 한다. 다음은 HTTPS로 보호되는 연결을 통해 권한 부여 요청 데이터를 AS에 직접 보내는 이러한 pushed authorization request의 예이다:

  POST /as/par HTTP/1.1
  Host: as.example.com
  Content-Type: application/x-www-form-urlencoded
  Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

  response_type=code&
  client_id=s6BhdRkqt3
  &state=af0ifjsldkj
  &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
  &code_challenge_method=S256
  &code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bwc-uCHaoeK1t8U
  &authorization_details=%5B%7B%22type%22%3A%22account_information%22
  %2C%22actions%22%3A%5B%22list_accounts%22%2C%22read_balances%22%2C%
  22read_transactions%22%5D%2C%22locations%22%3A%5B%22https%3A%2F%2Fe
  xample.com%2Faccounts%22%5D%7D%2C%7B%22type%22%3A%22payment_initiat
  ion%22%2C%22actions%22%3A%5B%22initiate%22%2C%22status%22%2C%22canc
  el%22%5D%2C%22locations%22%3A%5B%22https%3A%2F%2Fexample.com%2Fpaym
  ents%22%5D%2C%22instructedAmount%22%3A%7B%22currency%22%3A%22EUR%22
  %2C%22amount%22%3A%22123.50%22%7D%2C%22creditorName%22%3A%22Merchan
  t123%22%2C%22creditorAccount%22%3A%7B%22iban%22%3A%22DE021001001093
  07118603%22%7D%2C%22remittanceInformationUnstructured%22%3A%22Ref%2
  0Number%20Merchant%22%7D%5D
그림 24: "authorization_details"를 포함하는 큰 요청의 예

12. 보안 고려 사항

OAuth 권한 부여 요청의 경우 authorization_details 매개변수는 사용자 에이전트를 통해 전송되며, 이로 인해 사용자의 수정에 취약해진다. authorization_details의 무결성이 문제가 되는 경우, 클라이언트는 authorization_details를 변조 및 바꿔치기로부터 보호해야 MUST 한다. 이는 [RFC9101]에 정의된 서명된 요청 객체를 사용하여 요청을 서명하거나, [RFC9101]에 정의된 request_uri 권한 부여 요청 매개변수를 [RFC9126]와 함께 사용하여 요청 객체의 URI를 AS에 전달함으로써 달성할 수 있다.

authorization_details 매개변수의 모든 문자열 비교는 [RFC8259]에 정의된 대로 수행되어야 한다. 문자열 값의 동등성을 평가할 때 추가 변환이나 정규화는 수행되지 않아야 한다.

공통 데이터 필드 locations는 클라이언트가 특정 권한 부여를 어디에서 사용하려는지 지정할 수 있게 한다. 즉, 권한을 RS에 명확히 할당할 수 있다. 여러 RS가 있는 상황에서 이는 audience 제한을 통해 의도치 않은 클라이언트 권한 부여 (예: 이메일 및 클라우드 서비스 모두에 잠재적으로 적용될 수 있는 read scope 값)를 방지한다.

AS는 주입 공격을 방지하기 위해 authorization_details에 전달된 데이터를 적절히 정리하고 처리해야 MUST 한다.

[RFC6749], [RFC7662], 및 [RFC8414]의 보안 고려 사항도 적용된다.

13. 프라이버시 고려 사항

구현자가 권한 부여 세부 정보를 프라이버시를 보존하는 방식으로 설계하고 사용하는 것은 특히 중요하다.

authorization_details에 포함된 모든 민감한 개인정보는 예를 들어 referrer 헤더를 통해 누출되지 않도록 방지되어야 한다. 구현 옵션에는 [RFC9101]에 정의된 암호화된 요청 객체, 또는 [RFC9126][RFC9101]에 정의된 request_uri 권한 부여 요청 매개변수를 활용하여 클라이언트와 AS 간의 종단 간 암호화된 연결을 통해 authorization_details를 전송하는 것이 포함된다. 후자는 애플리케이션 수준 암호화를 요구하지 않지만, 클라이언트와 AS 간에 또 다른 메시지 교환을 요구한다.

요청 데이터가 암호화되어 있더라도, 공격자는 자신이 제어하는 디바이스의 권한 부여 요청에 암호화된 요청 데이터를 주입하고 AS의 사용자 동의 화면을 사용하여 (복호화된) 사용자 데이터를 평문으로 보여주게 함으로써 AS를 이용해 사용자의 데이터를 알아낼 수 있다. 구현은 이 공격 벡터를 고려하고, 예를 들어 데이터의 일부만 표시하거나 가능한 경우 가정된 사용자 맥락이 (사용자 인증 후에도) 여전히 동일한지 판단하는 것과 같은 적절한 대응책을 구현해야 한다.

AS는 authorization_details를 클라이언트 또는 RS와 공유할 때의 프라이버시 영향을 고려해야 한다. AS는 로컬 정책에 의해 결정되는 "알 필요가 있는" 기준에 따라 이 데이터를 해당 당사자들과 공유해야 한다.

14. IANA 고려 사항

14.1. OAuth 매개변수 등록

다음 매개변수는 [RFC6749]에 의해 설정된 "OAuth Parameters" 레지스트리 [IANA.OAuth.Parameters]에 등록되었다.

이름:
authorization_details
매개변수 사용 위치:
권한 부여 요청, 토큰 요청, 토큰 응답
변경 관리 주체:
IETF
참조:
RFC 9396

14.2. JSON Web Token 클레임 등록

다음 값은 [RFC7519]에 의해 설정된 IANA "JSON Web Token Claims" 레지스트리에 등록되었다.

클레임 이름:
authorization_details
클레임 설명:
클레임 authorization_details는 액세스 토큰의 권리를 나타내는 JSON 객체의 JSON 배열을 포함한다. 각 JSON 객체는 특정 타입의 리소스에 대한 권한 부여 요구 사항을 지정하는 데이터를 포함한다.
변경 관리 주체:
IETF
참조:
RFC 9396의 섹션 9.1

14.3. OAuth 토큰 인트로스펙션 응답 등록

다음 값은 [RFC7662]에 의해 설정된 IANA "OAuth Token Introspection Response" 레지스트리에 등록되었다.

이름:
authorization_details
설명:
멤버 authorization_details는 액세스 토큰의 권리를 나타내는 JSON 객체의 JSON 배열을 포함한다. 각 JSON 객체는 특정 타입의 리소스에 대한 권한 부여 요구 사항을 지정하는 데이터를 포함한다.
변경 관리 주체:
IETF
참조:
RFC 9396의 섹션 9.2

14.4. OAuth 권한 부여 서버 메타데이터 등록

다음 값은 [RFC8414]에 의해 설정된 [IANA.OAuth.Parameters]의 IANA "OAuth Authorization Server Metadata" 레지스트리에 등록되었다.

메타데이터 이름:
authorization_details_types_supported
메타데이터 설명:
AS가 지원하는 권한 부여 세부 정보 타입을 포함하는 JSON 배열
변경 관리 주체:
IETF
참조:
RFC 9396의 섹션 10

14.5. OAuth 동적 클라이언트 등록 메타데이터 등록

다음 값은 [RFC7591]에 의해 설정된 [IANA.OAuth.Parameters]의 IANA "OAuth Dynamic Client Registration Metadata" 레지스트리에 등록되었다.

클라이언트 메타데이터 이름:
authorization_details_types
클라이언트 메타데이터 설명:
클라이언트가 어떤 권한 부여 세부 정보 타입을 사용하는지 나타낸다.
변경 관리 주체:
IETF
참조:
RFC 9396의 섹션 10

14.6. OAuth 확장 오류 등록

다음 값은 [RFC6749]에 의해 설정된 [IANA.OAuth.Parameters]의 IANA "OAuth Extensions Error Registry"에 등록되었다.

이름:
invalid_authorization_details
사용 위치:
토큰 엔드포인트, 권한 부여 엔드포인트
프로토콜 확장:
OAuth 2.0 Rich Authorization Requests
변경 관리 주체:
IETF
참조:
RFC 9396의 섹션 5

15. 참고 문헌

15.1. 규범적 참고 문헌

[RFC2119]
Bradner, S., "RFC에서 요구 수준을 나타내는 데 사용하는 핵심 단어", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/info/rfc7662>.
[RFC8174]
Leiba, B., "RFC 2119 핵심 단어의 대문자와 소문자 모호성", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8628]
Denniss, W., Bradley, J., Jones, M., and H. Tschofenig, "OAuth 2.0 Device Authorization Grant", RFC 8628, DOI 10.17487/RFC8628, , <https://www.rfc-editor.org/info/rfc8628>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "OAuth 2.0을 위한 리소스 지시자", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.

15.2. 정보성 참고 문헌

[CSC]
Cloud Signature Consortium, "원격 서명 애플리케이션을 위한 아키텍처 및 프로토콜", Version 1.0.4.0, , <https://cloudsignatureconsortium.org/wp-content/uploads/2020/01/CSC_API_V1_1.0.4.0.pdf>.
[ETSI]
ETSI, "전자 서명 및 인프라스트럭처(ESI); 원격 디지털 서명 생성을 위한 프로토콜", V1.1.1, ETSI TS 119 432, , <https://www.etsi.org/deliver/etsi_ts/119400_119499/119432/01.01.01_60/ts_119432v010101p.pdf>.
[IANA.OAuth.Parameters]
IANA, "OAuth Parameters", <https://www.iana.org/assignments/oauth-parameters>.
[JSON.Schema]
OpenJS Foundation, "JSON Schema", <https://json-schema.org/>.
[OID-CIBA]
Fernandez, G., Walter, F., Nennker, A., Tonge, D., and B. Campbell, "OpenID Connect Client-Initiated Backchannel Authentication Flow - Core 1.0", , <https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html>.
[OIDC]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "정오표 세트 1을 포함한 OpenID Connect Core 1.0", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[RFC0020]
Cerf, V., "네트워크 교환을 위한 ASCII 형식", STD 80, RFC 20, DOI 10.17487/RFC0020, , <https://www.rfc-editor.org/info/rfc20>.
[RFC6749]
Hardt, D., Ed., "OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC8259]
Bray, T., Ed., "JavaScript Object Notation (JSON) 데이터 교환 형식", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC9101]
Sakimura, N., Bradley, J., and M. Jones, "OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)", RFC 9101, DOI 10.17487/RFC9101, , <https://www.rfc-editor.org/info/rfc9101>.
[RFC9126]
Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", RFC 9126, DOI 10.17487/RFC9126, , <https://www.rfc-editor.org/info/rfc9126>.
[Transaction-Auth]
Lodderstedt, T., "거래 권한 부여 또는 OAuth scope를 다시 생각해야 하는 이유", , <https://medium.com/oauth-2/transaction-authorization-or-why-we-need-to-re-think-oauth-scopes-2326e2038948>.

부록 A. 추가 예제

A.1. OpenID Connect

OpenID Connect [OIDC]는 클라이언트(OpenID Connect Relying Party로 동작)가 세분화되고 프라이버시를 보존하는 방식으로 수신하고자 하는 클레임을 지정할 수 있으며, 또한 해당 클레임을 특정 전달 메커니즘, 즉 ID Token 또는 userinfo 응답에 할당할 수 있는 JSON 기반 claims 요청 매개변수를 지정한다.

scope 값 openid와 추가 매개변수 claims의 조합은 모든 비-OIDC scope 값과 동일한 방식으로 같은 요청에서 authorization_details와 함께 사용될 수 있다.

또는 OpenID Connect에 대한 권한 부여 세부 정보 타입이 있을 수 있다. 이 섹션은 그러한 권한 부여 세부 정보 타입이 어떻게 보일 수 있는지의 예를 제공하지만, 이 권한 부여 세부 정보 타입을 정의하는 것은 이 명세의 범위를 벗어난다.

이러한 가상의 예제는 권한 부여 과정의 OpenID Connect 부분에 특화된 모든 세부 사항을 권한 부여 JSON 객체 하나에 캡슐화하려고 한다.

최상위 필드는 [OIDC]에 주어진 정의를 기반으로 한다:

claim_sets:
profile과 같은 해당 scope 값의 대체로서, 미리 정의된 클레임 집합의 이름
max_age:
최대 인증 경과 시간
acr_values:
요청된 인증 컨텍스트 클래스 참조(ACR) 값
claims:
[OIDC]에 정의된 claims JSON 구조

이는 몇 가지 클레임 집합에 대한 간단한 요청이다.

[
   {
      "type": "openid",
      "locations": [
         "https://op.example.com/userinfo"
      ],
      "claim_sets": [
         "email",
         "profile"
      ]
   }
]
그림 25: "authorization_details"를 활용하는 OpenID Connect 요청의 예

더 정교한 예는 그림 26에 표시된다.

[
   {
      "type": "openid",
      "locations": [
         "https://op.example.com/userinfo"
      ],
      "max_age": 86400,
      "acr_values": "urn:mace:incommon:iap:silver",
      "claims": {
         "userinfo": {
            "given_name": {
               "essential": true
            },
            "nickname": null,
            "email": {
               "essential": true
            },
            "email_verified": {
               "essential": true
            },
            "picture": null,
            "http://example.com/claims/groups": null
         },
         "id_token": {
            "auth_time": {
               "essential": true
            }
         }
      }
   }
]
그림 26: "authorization_details"를 활용하는 OpenID Connect 요청의 고급 예

A.2. 원격 전자 서명

다음 예제는 ETSI TS 119 432 [ETSI] 및 원격 서명 생성을 위한 Cloud Signature Consortium (CSC) API [CSC]에서 제시된 원격 전자 서명의 개념을 기반으로 한다.

[
   {
      "type": "sign",
      "locations": [
         "https://signing.example.com/signdoc"
      ],
      "credentialID": "60916d31-932e-4820-ba82-1fcead1c9ea3",
      "documentDigests": [
         {
            "hash": "sTOgwOm+474gFj0q0x1iSNspKqbcse4IeiqlDg/HWuI=",
            "label": "Credit Contract"
         },
         {
            "hash": "HZQzZmMAIWekfGH0/ZKW1nsdt0xg3H6bZYztgsMTLw0=",
            "label": "Contract Payment Protection Insurance"
         }
      ],
      "hashAlgorithmOID": "2.16.840.1.101.3.4.2.1"
   }
]
그림 27: 전자 서명의 예

최상위 필드는 다음 의미를 가진다:

credentialID:
서명에 사용할 인증서의 식별자
documentDigests:
서명할 각 문서의 해시(hash 필드)를 포함하는 배열. 또한 해당 label 필드는 예를 들어 사용자 동의에 사용될 수 있도록 각각의 문서를 사용자에게 식별한다.
hashAlgorithm:
해시 값을 계산하는 데 사용된 알고리즘

AS는 이 구조에 나열된 문서에 대한 서명 생성을 위해 사용자에게 동의를 요청해야 한다. 클라이언트는 이 과정의 결과로 발급된 액세스 토큰을 사용하여 각각의 서명 서비스에서 문서 서명 API를 호출하고 실제로 서명을 생성한다. 이 액세스 토큰은 사용자 동의에 따라 클라이언트, 사용자 ID, 해시(및 서명 알고리즘)에 바인딩된다.

A.3. 세금 데이터에 대한 액세스

이 예제는 제3자가 예를 들어 신용도를 판단하기 위해 시민의 세금 신고서 및 소득 명세서에 액세스할 수 있도록 하는 API에서 영감을 받았다.

[
    {
        "type": "tax_data",
        "locations": [
            "https://taxservice.govehub.no.example.com"
        ],
        "actions":"read_tax_declaration",
        "periods": ["2018"],
        "duration_of_access": 30,
        "tax_payer_id": "23674185438934"
    }
]
그림 28: 세금 데이터 액세스의 예

최상위 필드는 다음 의미를 가진다:

periods:
클라이언트가 액세스하려는 기간
duration_of_access:
클라이언트가 데이터에 액세스하려는 기간(일 단위)
tax_payer_id:
납세자의 식별자(클라이언트가 알고 있는 경우)

A.4. eHealth

이 두 예제는 노르웨이 eHealth 시스템에서 사용되는 API에 대한 요구 사항에서 영감을 받았다.

이 사용 사례에서 물리치료사는 로컬 Electronic Health Records (EHR) 시스템을 사용하는 컴퓨터 앞에 앉아 있다. 그는 특정 환자의 전자 환자 기록을 보고자 하며, 다른 시스템, 아마도 다른 기관이나 국가 서비스에 있는 환자의 진료 기록 항목도 가져오고자 한다. 이 데이터에 대한 액세스는 API로 제공된다.

API에서 요청에 권한을 부여하는 데 필요한 정보는 EHR 시스템만 알고 있으며, API에 제시되어야 한다.

첫 번째 예에서 권한 부여 세부 정보 객체는 조직의 식별자를 포함한다. 이 경우 API는 주어진 조직이 민감한 데이터에 대한 액세스를 제공하기 위해 개인 건강 정보를 처리할 법적 근거를 가지고 있는지 알아야 한다.

"authorization_details": {
    "type": "patient_record",
    "requesting_entity": {
        "type": "Practitioner",
        "identifier": [
        {
            "system": "urn:oid:2.16.578.1.12.4.1.4.4",
            "value": "1234567"
        }],
        "practitioner_role": {
            "organization": {
                "identifier": {
                    "system": "urn:oid:2.16.578.1.12.4.1.2.101",
                    "type": "ENH",
                    "value": "[organizational number]"
                }
            }
        }
    }
}
그림 29: eHealth 예

두 번째 예에서 API는 요청에 권한을 부여하기 위해 더 많은 정보를 요구한다. 이 경우 권한 부여 세부 정보 객체는 의료 기관과 요청 시점에 사용자가 가진 현재 직업에 대한 추가 정보를 포함한다. 추가적인 세부 수준은 권한 부여와 데이터 최소화 모두에 사용될 수 있다.

[
   {
      "type": "patient_record",
      "location": "https://fhir.example.com/patient",
      "actions": [
         "read"
      ],
      "patient_identifier": [
         {
            "system": "urn:oid:2.16.578.1.12.4.1.4.1",
            "value": "12345678901"
         }
      ],
      "reason_for_request": "Clinical treatment",
      "requesting_entity": {
         "type": "Practitioner",
         "identifier": [
            {
               "system": "urn:oid:2.16.578.1.12.4.1.4.4",
               "value": "1234567"
            }
         ],
         "practitioner_role": {
            "organization": {
               "identifier": [
                  {
                     "system": "urn:oid:2.16.578.1.12.4.1.2.101",
                     "type": "ENH",
                     "value": "<organizational number>"
                  }
               ],
               "type": {
                  "coding": [
                     {
                        "system":
                           "http://hl7.example.org/fhir/org-type",
                        "code": "dept",
                        "display": "Hospital Department"
                     }
                  ]
               },
               "name": "Akuttmottak"
            },
            "profession": {
               "coding": [
                  {
                     "system": "http://snomed.example.org/sct",
                     "code": "36682004",
                     "display": "Physical therapist"
                  }
               ]
            }
         }
      }
   }
]
그림 30: 고급 eHealth 예

필드 설명:

patient_identifier:
OID 형식의 시스템 식별자(네임스페이스)와 이 네임스페이스 내 실제 값으로 구성된 환자의 식별자.
reason_for_request:
사용자가 특정 API에 액세스하려는 이유.
requesting_entity:
신원, 역할 및 조직적 맥락을 통해 요청자를 명세한 것. 이 데이터는 권한 부여를 용이하게 하고 감사 목적으로 제공된다.

이 사용 사례에서 AS는 환자가 아닌 요청자를 인증하고 정책에 기반하여 액세스를 승인한다.

감사의 말

이 명세를 준비하는 동안 귀중한 피드백을 제공해 준 Daniel Fett, Sebastian Ebling, Dave Tonge, Mike Jones, Nat Sakimura, 및 Rob Otto에게 감사한다.

또한 이 명세에 귀중한 피드백을 제공해 준 Vladimir Dzhuvinov, Takahiko Kawasaki, Daniel Fett, Dave Tonge, Travis Spencer, Joergen Binningsboe, Aamund Bremer, Steinar Noem, Francis Pouatcha, Jacob Ideskog, Hannes Tschofenig, 및 Aaron Parecki에게도 감사한다.

저자 주소

Torsten Lodderstedt
yes.com
Justin Richer
Bespoke Engineering
Brian Campbell
Ping Identity