OAuth 1.0

OAuth 1.0에 관한 핵심 내용을 번역하여 정리합니다.

OAuth 1.0에 관한 RFC 명세([링크]가 따로 존재하긴 하지만, 분량이 워낙 길다보니 고민 끝에 핵심적인 내용만 정리된 별도의 문서를 번역하기로 했습니다. OAuth 1.0은 취약점이 발견되어 더이상 사용을 권장하지 않는 기술이지만 현재 사용되는 OAuth 2.0을 이해하는 데에 도움이 되지 않을까 싶어 정리해둡니다.

요약

OAuth 프로토콜은 웹사이트 혹은 애플리케이션(소비자)이 사용자에게 서비스 제공자의 인증 정보를 요구할 필요 없이 API를 통해 웹 서비스(서비스 제공자)로부터 보호된 리소스에 접근하는 것을 가능케 한다. 더 일반적으로, OAuth는 API 인가에 대해 자유롭게 구현 가능하고 일반적인 방법론을 만든다.

프린팅 서비스인 printer.example.com(소비자)을 예로 들면, photos.example.net(서비스 제공자)에 사용자가 printer.example.com에 photos.example.net의 인증 정보를 제공할 필요 없이 저장된 개인 사진에 접근을 허용하는 것이다.

OAuth는 특정한 사용자 인터페이스나 상호작용 패턴을 요구하지 않으며, 서비스 제공자가 사용자를 인증하는 방법을 명시하지도 않기 때문에, OpenID와 같이 사용자가 인증 정보를 사용할 수 없는 사례에 이상적으로 적합하다.

OAuth는 위임된(delegated) 웹 서비스 인증의 경험과 구현을 하나의 커뮤니티 주도 프로토콜로 통합하는 것을 목표로 한다. OAuth는 여러 웹사이트에 의해 독립적으로 구현되어 온 기존의 프로토콜과 좋은 사례들을 기반으로 한다. 크고 작은 제공자들 모두가 지원하는 하나의 개방 표준은 애플리케이션들의 개발자와 사용자 양 쪽에게 일관되고 믿을 수 있는 경험을 촉진한다.

2. 표기 및 관례

원문의 내용 중 RFC2119에 기술된 키워드는 링크의 내용 따른 형태로 번역되었다.

3. 정의

서비스 제공자(Service Provider)
OAuth를 통한 액세스를 허용하는 웹 애플리케이션.
사용자(User)
서비스 제공자의 계정을 가지고 있는 개인.
소비자(Consumer)
사용자를 대신하여 서비스 제공자에 접근하기 위해 OAuth를 사용하는 웹사이트 혹은 애플리케이션.
보호된 리소스(Protected Resource(s))
소비자가 인증을 통해 접근할 수 있는, 서비스 제공자에 의해 통제되는 데이터.
소비자 개발자(Consumer Developer)
소비자를 구현하는 개인 혹은 조직.
소비자 키(Consumer Key)
서비스 제공자에게 소비자가 자신을 식별하기 위해 사용되는 값.
소비자 시크릿(Consumer Secret)
소비자가 소비자 키의 소유권을 확실히 하기 위한 시크릿.
요청 토큰(Request Token)
소비자가 사용자로부터 인가를 얻고 접근 토큰과 교호나하는 데 사용되는 값.
접근 토큰(Access Token)
사용자의 서비스 제공자 인증 정보 대신, 소비자가 사용자를 대신하여 보호된 리소스에 접근하는 데에 사용되는 값.
토큰 시크릿(Token Secret)
소비자가 주어진 토큰의 소유권을 확실히 하는 데 사용되는 시크릿.
OAuth 프로토콜 파라미터(OAuth Protocol Parameter)
이름이 oauth_로 시작하는 파라미터

4. 문서화와 등록

OAuth는 서비스 제공자에게 (사용자와는 대조적으로)소비자를 인증하는 소비자 키와 일치하는 소비자 시크릿을 포함해야 한다. 소비자 구체적인 식별은 서비스 제공자가 (리소스에 대한 제한 없는 요청과 같이)소비자에 따라 접근 수준을 달리할 수 있도록 한다.

소비자 시크릿이 소비자와 서비스 제공자 외에 어느 누구에게도 접근될 수 없다고 알려지지 않은 이상, 서비스 제공자는 소비자의 신분을 확인하는 방법으로 소비자 시크릿에 의존하지 않는 것이 좋다. (예를 들어 소비자 확인이 필요하지 않은 경우 혹은, RSA와 같이 다른 방법을 통해 확인이 이루어진 경우)소비자 시크릿은 빈 문자열일 수도 있다.

4.1. 요청 URL

OAuth는 세 URL을 정의한다:

요청 토큰 URL
인가되지 않은 요청 토큰을 얻기 위한 URL, [Section 6.1]에 설명됨.
사용자 인가 URL
소비자 접근을 위해 사용자 인가를 얻는 데에 사용되는 URL, [Section 6.2]에 설명됨.
접근 토큰 URL
사용자 인가된 요청 토큰을 접근 토큰으로 교환하는 데에 사용되는 URL, [Section 6.3]에 설명됨.

세 URL은 스키마, 권한, 경로(path)를 포함해야 하며, [RFC3986]의 Section 3에 정의된 쿼리와 프래그먼트를 포함할 수 있다. 요청 URL 쿼리는 어떤 OAuth 프로토콜 파라미터도 포함해서는 안된다. 예를 들어:

http://sp.example.com/authorize

4.2. 서비스 제공자

서비스 제공자의 책임은 소비자 개발자가 소비자 키와 소비자 시크릿을 설정하는 것을 가능케 하는 것이다. 이러한 권한 설정에 대한 프로세스와 요구사항은 전적으로 서비스 제공자에게 달려 있다.

서비스 제공자의 문서는 다음을 포함해야 한다:

  1. 소비자가 OAuth 요청을 만들 때 사용할 [4.1 URL]과 요청 토큰 URL과 접근 토큰 URL에서 사용되는 HTTP 메서드 (i.e. GET, POST, etc.).
  2. 서비스 제공자에 의해 지원되는 서명 방법.
  3. 토큰을 얻기 위해 서비스 제공자가 요구하는 추가적인 임의의 파라미터. 서비스 제공자가 명시하는 파라미터는 oauth_로 시작해서는 안된다.

4.3 소비자

소비자 개발자는 서비스 제공자를 통해 소비자 키와 소비자 시크릿을 설정해야 한다. 소비자 개발자는 등록에 있어 서비스 제공자에게 추가적인 정보를 제공하도록 요구받을 수도 있다.

5. 파라미터

OAuth 프로토콜 파라미터 이름과 값은 대소문자를 구분한다. 각 OAuth 프로토콜 파라미터는 매 요청에 한번 이상 나타나서는 안되며, 달리 명시되지 않으면 필수이다.

5.1. 파라미터 인코딩

모든 파라미터 이름과 값은 [RFC3986] 퍼센트-인코딩(%xx) 메커니즘을 사용하여 이스케이프된다. 예약되지 않은 문자 셋([RFC3986] Section 2.3)에 있지 않은 문자는 인코딩되어야 한다. 예약되지 않은 문자 셋에 있는 문자는 인코딩되서는 안된다. 인코딩에서 16진수 문자는 대문자여야 한다. 텍스트 이름과 값은 [RFC3629]로 퍼센트-인코딩하기 전에 UTF-8 옥텟으로 인코딩되어야 한다.

unreserved = ALPHA, DIGIT, '-', '.', '-', '~'

5.2. 소비자 요청 파라미터

OAuth 프로토콜 파라미터는 세 가지 방법 중의 하나로 소비자로부터 서비스 제공자에게 전송된다. 선호도가 감소하는 순서:

  1. [5.4 OAuth HTTP Authorization Scheme]에 정의된 HTTP Authorization 헤더 안에.
  2. content-type이 application/x-www-form-urlencoded인 HTTP POST 요청의 바디로써.
  3. URL의 쿼리 부분에 추가되어([RFC3986] section 3에 정의된 대로)

    정의된 방법들에 추가로, 미래의 확장들은 OAuth 프로토콜 파라미터를 전송하는 대체 방법들을 기술할 수도 있다. 다른 요청 파라미터를 보내기 위한 방법은 정의되지 않은 채로 남겨지지만, 5.4 OAuth HTTP Authorization Scheme 헤더는 사용하지 않는 것이 좋다.

5.3. 서비스 제공자 응답 파라미터

응답 파라미터는 HTTP 응답 바디에서 토큰과 소비자에 대한 다른 정보를 반환하여 서비스 제공자에 의해 전송돼야 한다. 파라미터 이름과 값은 먼저 각 [5.1 파라미터 인코딩]에 따라 인코딩 되어야 하며, [RFC3986] Section 2.1에 정의된 대로 ‘&’ 문자(ASCII 코드 38)로 이어붙여진다. 예를 들어:

oauth_token=ab3cd9j4ks73hf7g&oauth_token_secret=xyz4992k83j47x0b

5.4. OAuth HTTP Authorization 스키마

이 절에서는 OAuth를 지원하기 위해 [RFC2617] 확장을 정의한다. 이는 OAuth 프로토콜 파라미터를 전달하기 위해 표준 HTTP의 Authorization 과 WWW-Authenticate 헤더를 사용한다.

서비스 제공자는 HTTP Authorization 헤더를 수용하는 것이 권장된다. 소비자는 OAuth Authorization 헤더에서 OAuth 프로토콜 파라미터를 전송할 수 있게 하는 것이 좋다.

([RFC2617]에 정의된 대로) 확장 인가-스키마는 OAuth이며 대소문자를 구별한다.

5.4.1. Authorization 헤더

OAuth 프로토콜 파라미터는 Authorization 헤더에서 다음의 방법으로 전송된다:

  1. 파라미터 이름과 값은 [5.1 파라미터 인코딩]으로 인코딩된다.

  2. 각 파라미터마다, 이름은 바로 뒤에 ‘=’ 문자(ASCII 코드 61), ‘“’ 문자(ASCII 코드 34), 파라미터 값 (비어있을 수도 있음), 그리고 또 다른 ‘”’ 문자(ASCII 코드 34)가 붙는다.

  3. 파라미터는 쉼표 문자(ASCII 코드 44)와 선택적으로 [RFC2617]의 선형 화이트스페이스로 구분된다.

  4. [RFC2617] Section 1.2에 따라 선택적으로 realm 파라미터가 추가되고 해석된다. 예를 들어:

    Authorization: OAuth realm="http://sp.example.com/",
    oauth_consumer_key="0685bd9184jfhq22",
    oauth_token="ad180jjd733klru7",
    oauth_signature_method="HMAC-SHA1",
    oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
    oauth_timestamp="137131200",
    oauth_nonce="4572616e48616d6d65724c61686176",
    oauth_version="1.0"
    

5.4.2. WWW-Authenticate 헤더

서비스 제공자는 보호된 리소스에 대한 소비자 요청에 대해 OAuth HTTP WWW-Authenticate 헤더를 반환함으로써 확장에 대한 지원을 나타낼 수 있다. [RFC2617]에 따라 이러한 응답은 추가적인 HTTP WWW-Authenticate 헤더들을 포함할 수도 있다.

예를 들어:

WWW-Authenticate: OAuth realm="http://sp.example.com/"

realm 파라미터는 [RFC2617] Section 1.2에 따라 보호 영역을 정의한다.

6. OAuth를 이용한 인증

OAuth 인증은 사용자가 인증 정보를 소비자와 공유하지 않으면서 자신의 보호된 리소스에 대한 접근을 허용하는 과정이다. OAuth는 사용자의 보호된 리소스 요청에 대한 인증 정보 대신 서비스 제공자에 의해 생성된 토큰을 사용한다. 이 과정은 두 개의 토큰 유형을 사용한다.

요청 토큰
사용자에게 보호된 리소스에 대한 접근을 인가받기 위해 소비자에 의해 사용된다. 사용자 인가된 요청은 접근 토큰으로 교환되며, 단 한번만 사용되어야 하고, 임의의 다른 목적으로 사용되어서는 안된다. 요청 토큰은 제한된 수명을 갖도록 하는 것이 좋다.
접근 토큰
사용자를 대신하여 제한된 리소스에 접근하기 위해 소비자에 의해 사용된다. 접근 토큰은 특정한 보호된 리소스에 대한 접근으로 제한할 수 있으며, 제한된 수명을 가질 수 있다. 서비스 제공자는 사용자가 접근 토큰을 취소할 수 있도록 해야 한다. 오직 접근 토큰만이 제한된 리소스에 접근하는 데에 사용되는 것이 좋다.

OAuth 인증은 3 단계에 의해 이루어진다:

  1. 소비자가 인가되지 않은 요청 토큰을 얻는다.
  2. 사용자가 요청 토큰을 인가한다.
  3. 소비자가 요청 토큰을 접근 토큰으로 교환한다.

diagram (출처: https://oauth.net/core/1.0/)

6.1. 인가되지 않은 요청 토큰 획득

소비자는 서비스 제공자에게 토큰 발급을 요청하여 인가되지 않은 요청 토큰을 얻는다. 이 요청 토큰의 유일한 목적은 사용자의 허가를 받는 것이며 오직 접근 토큰을 얻는 데에만 사용될 수 있다. 요청 토큰 프로세스는 다음과 같다:

6.1.1. 소비자가 요청 토큰을 얻는다

요청 토큰을 얻기 위해, 소비자는 서비스 제공자의 요청 토큰 URL에 HTTP 요청을 보낸다. 서비스 제공자 문서는 이 요청에 대한 HTTP 메서드를 명시하며, HTTP POST가 권장된다. 요청은 서명되어야 하며 다음 파라미터를 포함한다.

oauth_consumer_key
소비자 키.
oauth_signature_method
소비자가 요청에 서명하는 데 사용한 서명 방법.
oauth_signature
[9. 요청 서명]에 정의된 서명.
oauth_timestamp
[8. 넌스와 타임스탬프]에 정의된 값.
oauth_nonce
[8. 넌스와 타임스탬프]에 정의된 값.
oauth_versiohn
선택사항. 만약 있는 경우, 값은 1.0이어야 한다. 서비스 제공자는 이 파라미터가 없는 경우 프로토콜 버전을 1.0으로 가정해야 한다. 서비스 제공자가 1.0이 아닌 값으로 응답하는지는 정의되지 않은 채 남겨진다.
추가 파라미터
서비스 제공자에 의해 정의된 임의의 추가적인 파라미터.

6.1.2. 서비스 제공자가 인가되지 않은 요청 토큰을 발급

서비스 제공자는 서명과 소비자 키를 확인한다. 성공하면, 요청 토큰과 토큰 시크릿을 생성하고 이를 소비자에게 [5.3 서비스 제공자 응답 파라미터]에 정의된 대로 HTTP 응답 바디에 반환한다. 서비스 제공자는 요청 토큰이 [6.2 사용자 인가 획득]에서 성공적으로 사용자의 허가를 얻기 전까지 요청 토큰으로 교환될 수 없도록 해야 한다.

응답은 다음 파라미터를 포함한다.

oauth_token
요청 토큰
oauth_token_secret
토큰 시크릿
추가 파라미터
서비스 제공자에 의해 정의된 임의의 추가적인 파라미터.

요청이 확인에 실패하거나 다른 이유로 거절되면, 서비스 제공자는 [10. HTTP 요청 코드]에 정의된 적절한 응답 코드로 반응하는 것이 좋다. 서비스 제공자는 HTTP 응답에서 왜 요청이 거절되었는지에 대한 세부 사항을 [5.3 서비스 제공자 응답 파라미터]에 정의된 응답 바디에 포함할 수도 있다.

6.2. 사용자 인가 획득

소비자는 요청 토큰이 사용자에 의해 인가되기 전까지 사용할 수 없다. 사용자 인가 획득은 다음 단계를 포함한다:

6.2.1. 소비자가 사용자를 서비스 제공자에게 안내

소비자가 요청 토큰을 접근 토큰으로 교환할 수 있도록 하기 위해, 소비자는 사용자를 서비스 제공자에게 안내함으로써 사용자에게 허가를 얻어야 한다. 소비자는 다음의 파라미터로 서비스 제공자의 사용자 인가 URL에 HTTP GET 요청을 보낸다.

oauth_token
선택사항. 이전 단계에서 얻은 요청 토큰이다. 서비스 제공자는 필수 사항으로 선언하거나, 사용자에게 직접 입력하도록 하는 경우에는 없이 요청을 받아들일 수도 있다.
oauth_callback
선택사항. 소비자는 서비스 제공자가 [6.2 사용자 인가 획득]을 완료했을 때 사용자를 소비자에게 돌려보내는 리다이렉트에 사용할 URL을 명시할 수도 있다.
추가 파라미터
서비스 제공자에 의해 정의된 임의의 추가적인 파라미터.

요청 URL이 생성되면 소비자는 사용자의 웹 브라우저를 통해 사용자를 URL로 리다이렉트한다. 소비자가 자동 HTTP 리다이렉션이 불가능하면, 소비자는 어떻게 수동으로 생성된 요청 URL로 찾아가는지 사용자에게 알려야 한다.

Note: 만약 서비스 제공자가 소비자가 모바일 장치 혹은 셋탑박스에서 동작한다는 것을 안다면, 서비스 제공자는 사용자 인가 URL과 요청 토큰이 수동 입력하기 적절함을 보장하는 것이 좋다.

6.2.2. 서비스 제공자가 사용자를 인증하고 동의를 얻음

서비스 제공자는 사용자의 신분을 확인하고 자세하게 동의를 구한다. OAuth는 서비스 제공자가 사용자를 인증하는 방법에 대해서는 명시하지 않는다. 하지만, 필수적인 단계들을 정의한다:

  • 서비스 제공자는 동의를 구하기 전에 먼저 사용자의 신분을 확인해야 한다. 만약 사용자가 아직 가입하지 않았다면 그렇게 하도록 유도할 수도 있다.
  • 서비스 제공자는 사용자에게 접근을 요청하는 (소비자 개발자에 의해 등록된)소비자에 관한 정보를 제공한다. 이 정보는 접근 기간과 제공되는 보호된 리소스를 포함한다.
  • 사용자는 서비스 제공자가 소비자에게 사용자를 대신하여 보호된 리소스에 접근할 권한을 부여하는 것을 허용하거나 거절해야 한다. 만약 사용자가 소비자의 접근을 거절하면, 서비스 제공자는 보호된 리소스에 접근하도록 해서는 안된다.

소비자 키에 기반하여 사용자에게 소비자에 대한 임의의 식별 정보를 표시할 때, 서비스 제공자는 이것이 소비자의 진짜 신분임을 보장할 수 없다는 것을 사용자에게 알려야 한다. 서비스 제공자가 사용자에게 알리는 방법과 신분을 보장하는 수준은 이 명세의 영역을 벗어난다.

6.2.3. 서비스 제공자가 사용자를 소비자에게 안내

사용자가 서비스 제공자와 함께 인증하고 소비자 접근에 대한 권한을 허용한 뒤에, 소비자는 요청 토큰이 인가되었으며 접근 토큰으로 교환할 준비가 되었음을 알려야 한다. 사용자가 접근을 거부하면, 소비자는 요청 토큰이 취소되었음을 알릴 수도 있다.

소비자가 ([6.2.1. 소비자가 사용자를 서비스 제공자에게 안내]에 기술된 대로) oauth_callback에서 콜백 URL을 제공한 경우, 서비스 제공자는 HTTP GET 요청 URL을 생성하고, 사용자의 웹 브라우저를 다음의 파라미터와 함께 리다이렉트한다:

oauth_token
사용자가 인가하거나 거절한 요청 토큰

콜백 URL은 소비자가 제공한 쿼리 파라미터를 포함할 수도 있다. 서비스 제공자는 이들을 변경되지 않은 채로 간직해야 하고, 기존 쿼리에 oauth_token 파라미터를 이어붙여야 한다.

만약 콜백 URL이 제공되지 않으면, 서비스 제공자는 사용자가 수동으로 소비자에게 인가가 완료되었음을 알리게 해야 한다.

6.3. 접근 토큰 획득

소비자는 요청 토큰을 보호된 리소스에 접근할 수 있는 접근 토큰으로 교환한다. 접근 토큰 획득은 다음 단계를 포함한다:

6.3.1. 소비자가 접근 토큰을 요청

요청 토큰과 토큰 시크릿은 접근 토큰과 토큰 시크릿으로 교환되어야 한다.

접근 토큰을 요청하기 위해, 소비자는 서비스 제공자의 접근 토큰 URL에 대한 HTTP 요청을 만든다. 서비스 제공자 문서는 이 요청에 대한 HTTP 메서드를 명시하며, HTTP POST 메서드가 권장된다. 요청은 [9. 요청 서명]에 따라 서명되어야 하고, 다음의 파라미터를 포함한다.

oauth_consumer_key
소비자 키.
oauth_token
이전에 획득한 요청 토큰.
oauth_signature_method
소비자가 요청을 서명하는데 사용한 서명 방법.
oauth_timestamp
[8. 넌스와 타임스탬프]에 정의된 값.
oauth_nonce
[8. 넌스와 타임스탬프]에 정의된 값.
oauth_version
선택사항. 만약 있는 경우, 값은 1.0이어야 한다. 서비스 제공자는 이 파라미터가 없는 경우 프로토콜 버전을 1.0으로 가정해야 한다. 서비스 제공자가 1.0이 아닌 값으로 응답하는지는 정의되지 않은 채 남겨진다.

사용자 허가를 받기 전에 모든 토큰에 관련된 정보가 있는지 확인하기 위해 접근 토큰을 요청할 때는 서비스 제공자에 구체적인 추가적인 파라미터는 허용되지 않는다.

6.3.2. 서비스 제공자가 접근 토큰을 승인

서비스 제공자는 다음을 확인해야 한다:

  • 요청 서명이 성공적으로 확인되었다.
  • 요청 토큰이 한번도 접근 토큰으로 교환된 적이 없다.
  • 요청 토큰이 소비자 키와 일치한다.

만약 성공하면, 서비스 제공자는 접근 토큰과 토큰 시크릿을 생성하고 [5.3 서비스 제공자 응답 파라미터]에 정의된 대로 HTTP 응답 바디에 반환한다. 접근 토큰과 토큰 시크릿은 소비자에 의해 저장되며 보호된 리소스 요청을 서명할 때 사용된다. 응답은 다음 파라미터를 포함한다:

oauth_token
접근 토큰.
oauth_token_secret
토큰 시크릿.
추가 파라미터
서비스 제공자에 의해 정의된 추가적인 파라미터.

요청이 확인에 실패하거나 다른 이유로 거절되면, 서비스 제공자는 [10. HTTP 요청 코드]에 정의된 적절한 응답 코드로 반응하는 것이 좋다. 서비스 제공자는 HTTP 응답에서 왜 요청이 거절되었는지에 대한 세부 사항을 [5.3 서비스 제공자 응답 파라미터]에 정의된 응답 바디에 포함할 수도 있다.

7. 보호된 리소스에 접근

성공적으로 접근 토큰과 토큰 시크릿을 받은 후, 소비자는 사용자를 대신하여 보호된 리소스에 접근할 수 있게 된다. 요청은 [9. 요청 서명]을 따라 서명되어야 하며, 다음의 파라미터를 포함한다.

oauth_consumer_key
소비자 키.
oauth_token
접근 토큰.
oauth_signature_method
소비자가 요청을 서명하는데 사용한 서명 방법.
oauth_timestamp
[8. 넌스와 타임스탬프]에 정의된 값.
oauth_nonce
[8. 넌스와 타임스탬프]에 정의된 값. oauth_version
선택사항. 만약 있는 경우, 값은 1.0이어야 한다. 서비스 제공자는 이 파라미터가 없는 경우 프로토콜 버전을 1.0으로 가정해야 한다. 서비스 제공자가 1.0이 아닌 값으로 응답하는지는 정의되지 않은 채 남겨진다.
추가 파라미터
서비스 제공자에 의해 정의된 임의의 추가적인 파라미터.

8. 넌스와 타임스탬프

서비스 제공자에 의해 달리 명시되지 않는 한, 타임스탬프는 GMT 1970년 1월 1일 00:00:00 이후 경과한 초 단위의 시간으로 표현된다. 타임스탬프 값은 양의 정수여야 하며, 이전 요청들에서 사용된 타임스탬프보다 크거나 같아야 한다.

소비자는 해당 타임스탬프의 모든 요청들에서 유일한 넌스 값(임시로 생성된 값)을 생성해야 한다. 넌스는 랜덤 문자열이며, 각 요청에 대해 고유하게 생성된다. 넌스는 서비스 제공자가 해당 요청이 한번도 만들어진 적이 없음을 확인할 수 있게 하며, 요청들이 (HTTP와 같은)비 보안 채널을 통해 만들어졌을 때 반복 공격을 예방하는데 도움을 준다.

9. 요청 서명

모든 토큰 요청과 보호된 리소스 요청은 소비자에 의해 서명되어야 하고 서비스 제공자에 의해 확인되어야 한다. 요청을 서명하는 목적은 미인가된 집단이 토큰 요청이나 보호된 리소스 요청을 만들 때 소비자 키와 토큰을 사용하는 것을 방지하기 위함이다. 서명 프로세스는 소비자 시크릿과 토큰 시크릿을 요청에 포함되어 확인 가능한 값으로 인코딩한다.

각 구현은 고유한 요구사항을 가질 수 있기 때문에, OAuth는 특정한 서명 방법을 사용하도록 지시하지 않는다. 프로토콜은 세 서명 방법을 정의한다: HMAC-SHA!, RSA-SHA1 및 PLAINTEXT, 하지만 서비스 제공자는 각자의 구현과 문서화에 있어 자유롭다. 특정한 임의의 메서드를 추천하는 것은 이 명세의 영역을 벗어난다.

소비자는 oauth_signature_method에서 서명 방법을 선언하고, 서명을 생성하고, 이를 oauth_signature에 저장한다. 서비스 제공자는 각 메서드에 명시된 서명으로 확인한다. 소비자 서명을 확인할 때, 서비스 제공자는 요청 넌스가 이전의 소비자 요청에서 사용된 적이 없는지 확인하는 것이 좋다.

oauth_signature 파라미터를 제외하고, 시그니처 프로세스는 요청 파라미터 이름이나 값을 변경해서는 안된다.

9.1. 서명 기반 문자열

서명 기반 문자열은 요청 요소들을 하나의 문자열로 일관되며 재생산 가능하도록(reproducible) 이어붙인 것이다. 이 문자열은 해싱이나 서명 알고리즘에 입력으로 사용된다. HMAC-SHA1 서명 방법이 서명 생성을 위해 서명 알고리즘을 사용하여 서명 기반 문자열을 사용하는 표준 및 예시를 제공한다. 모든 요청 파라미터는 서명 기반 문자열을 생성하기에 앞서 [5.1 파라미터 인코딩]에 기술된 대로 인코딩되어야 한다.

9.1.1. 요청 파라미터 정규화

요청 파라미터는 수집되고, 정렬되어 정규화된 문자열로 이어붙여진다:

  • realm 파라미터를 제외한 [5.4.1. OAuth HTTP Authorization 헤더]의 파라미터.
  • (content-type이 application/x-www-form-urlencoded인)HTTP POST 요청 바디의 파라미터.
  • ([RFC3986] Section 3에 정의된 대로)URL의 쿼리 부분에 추가된 HTTP GET 파라미터.

oauth_signature 파라미터는 제외되어야 한다.

파라미터는 다음과 같이 하나의 문자열로 정규화된다:

  1. 파라미터는 사전 순서 바이트 값 정렬을 사용하여 이름으로 정렬된다. 둘 혹은 그 이상의 파라미터가 같은 이름을 공유하면, 이들은 값 순서로 정렬된다, 예를 들어:

    a=1, c=hi%20there, f=25, f=50, f=a, z=p, z=t
    
  2. 파라미터는 정렬된 순서대로 하나의 문자열로 이어붙여진다. 각 파라미터에 대해, 값이 비어있더라도 이름은 ‘=‘문자(ASCII 코드 61)에 대응하는 값으로 구분된다. 각 이름-값 쌍은 ‘&’ 문자(ASCII 코드 38)로 구분된다. 예를 들어:

    a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t
    

9.1.2. 요청 URL 생성

서명 기반 문자열은 서명을 구체적인 엔드포인트로 묶는 요청 절대 URL을 포함한다. 서명 기반 문자열에서 사용되는 URL은 스키마, 권한, 경로(path)를 포함해야 하며, [RFC3986] Section 3에 에 정의된 쿼리와 프래그먼트를 제외해야 한다.

서비스 제공자가 절대 요청 URL을 사용할 수 없는 경우(소비자는 언제나 사용할 수 있다), 사용중인 스키마, HTTP Host 헤더, 그리고 상대 HTTP 요청 URL과 결합하여 생성될 수 있다. Host 헤더가 사용 불가능한 경우, 서비스 제공자는 문서나 다른 방법으로 소비자에게 전달되는 호스트 이름을 사용하는 것이 좋다.

URL 표준화에 따른 모호함을 피하기 위해 서비스 제공자는 서명 기반 문자열에서 사용되는 URL의 형식을 문서화하는 것이 좋다. 명시되지 않는 한, URL 스키마와 권한은 소문자여야 하며 포트 번호를 포함해야 한다; http 기본 포트 80과 https 기본 포트 443은 제외되어야 한다.

예를 들어 다음 요청은:

HTTP://Example.com:80/resource?id=123

다음과 같은 서명 기반 문자열에 포함된 수 있다:

http://example.com/resource

9.1.3. 요청 요소 연결

다음 항목들은 하나의 문자열로 연결되어야 한다. 각 항목은 비어있더라도 인코딩되고 ‘&’ 문자 (ASCII 코드 38)로 구분된다.

  1. HTTP 요청 메서드는 요청을 보내는 데 사용된다. 값은 대문자여야 한다, 예를 들어: HEAD, GET, POST, etc.
  2. [[Section 9.1.2.]][section-9-1-2]의 요청 URL
  3. [[Section 9.1.1.]][section-9-1-1]의 정규화된 요청 파라미터 문자열.

서명 기반 문자열 예시는 [Appendix A.5.1]을 참조.

9.2. HMAC-SHA1

HMAC-SHA1 서명 메서드는 [RFC2104]에 정의된 대로 HMAC-SHA1 서명 알고리즘을 사용하며, 여기서 서명 기반 문자열은 텍스트이고 키는 비어 있어도 ‘&‘문자 (ASCII 코드 38)로 구분되는 소비자 시크릿과 토큰 시크릿이 결합된 값이다.

9.2.1. 서명 생성

oauth_signature는 먼저 [RFC2045] Section 6.8의 base64 인코딩되어 계산된 digest 옥텟 문자열로 설정된다. 그 다음 [5.1 파라미터 인코딩]에 따라 인코딩된다.

9.2.2. 서명 확인

서비스 제공자는 새 서명 옥텟 문자열을 생성하고, 이를 소비자가 제공한 [5.1. 파라미터 인코딩]에 따라 URL 인코딩된 뒤 [RFC2045] Section 6.8. 에 따라 base64 디코딩된 서명과 비교함으로써 요청을 확인한다. 서명은 소비자가 제공한 요청 파라미터를 사용하여 생성되며, 소비자 시크릿과 토큰 시크릿은 서비스 제공자에 의해 저장된다.

9.3. RSA-SHA1

RSA-SHA1 서명 방법은 EMSA-PKCS1-v1_5에 대해 SHA-1을 해시 함수로 사용하는, (더 간단히는 PKCS#1으로 알려진 )[RFC3447] Section 8.2.에 정의된 RSASSA-PKCS1-v1_5 서명 알고리즘을 사용한다. 이는 소비자가 어떤 의미로는 이 명세의 영역을 벗어나는, 확인된 방법으로 자신의 RSA 공개 키를 서비스 제공자에게 제공했다고 가정한다.

9.3.1. 서명 생성

서명 기반 문자열은 소비자의 [RFC3447] Section 8.2.1.의 RSA 개인 키를 사용하여 서명된다, 여기서 K는 소비자의 KSA 개인 키이며, M은 서명 기반 문자열, S는 결과 서명의 옥텟 문자열이다:

    S = RSASSA-PKCS1-V1_5-SIGN (K, M)

oauth_signature는 먼저 [RFC2045] Section 6.8의 base64로 인코딩된 뒤 [5.1. 파라미터 인코딩]에 따라 URL 인코딩되어 S로 설정된다.

9.3.2. 서명 확인

서비스 제공자는 [RFC3447] Section 8.2.2.에 따라 서명을 확인한다. 여기서 (n, e)는 소비자의 RSA 공개 키, M은 서명 기반 문자열이고 S는 oauth_signature 값의 옥텟 문자열 표현이다:

    RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)

9.4. 평문(PLAIN TEXT)

9.4.1. 서명 생성

oauth_signature는 모든 시크릿이 비어 있어도 ‘&’ 문자(ASCII 코드 38)로 구분되는, 소비자 시크릿과 토큰 시크릿이 연결되어 인코딩된 값이다. 결과는 한번 더 인코딩되어야 한다.

이 예시들은 소비자 시크릿 djr9rjt0jd78jf88과 다른 세 토큰 시크릿에 대한 oauth_signature의 값을 보여준다:

jjd999tj88uiths3
    oauth_signature=djr9rjt0jd78jf88%26jjd999tj88uiths3
jjd99$tj88uiths3
    oauth_signature=djr9rjt0jd78jf88%26jjd99%2524tj88uiths3
Empty
    oauth_signature=djr9rjt0jd78jf88%26

9.4.2. 서명 확인

서비스 제공자는 서명 값을 소비자 시크릿과 토큰 시크릿으로 풀어서 요청을 확인하여 로컬에 저장된 시크릿과 일치함을 보장한다.

10. HTTP 응답 코드

이 절은 오직 요청 토큰과 접근 토큰 요청에만 적용한다. 일반적으로, 서비스 제공자는 [RFC2616] Section 10.에 정의된 응답 코드를 사용하는 것이 좋다. 서비스 제공자가 소비자 요청을 거절하면, HTTP 400 Bad Request 혹은 HTTP 401 Unauthorized로 응답하는 것이 좋다.

  • HTTP 400 Bad Request
    • 지원되지 않는 파라미터
    • 지원되지 않는 서명 방법
    • 필수 파라미터가 없음
    • 중복되는 OAuth 프로토콜 파라미터
  • HTTP 401 Unauthorized
    • 유요하지 않은 소비자 키
    • 유효하지 않거나 만료된 토큰
    • 유효하지 않은 서명
    • 유효하지 않거나 사용된 넌스

Appendix A.5.1. 서명 기반 문자열 생성

서명을 생성하기 위해, 먼저 서명 기반 문자열을 생성해야 한다. 요청은 순서에 따라 표준화된 문자열로 연결된 다음의 파라미터를 포함한다(oauth_signature는 제외되었다).

oauth_consumer_key
    dpf43f3p2l4k3l03
oauth_token
    nnch734d00sl2jdk
oauth_signature_method
    HMAC-SHA1
oauth_timestamp
    1191242096
oauth_nonce
    kllo9940pd9333jh
oauth_version
    1.0
file
    vacation.jpg
size
    original

다음의 입력들은 서명 기반 문자열을 생성하는 데 사용된다:

  1. GET
  2. http://photos.example.net/photos
  3. file=vacation.jpg&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1191242096&oauth_token=nnch734d00sl2jdk&oauth_version=1.0&size=original

서명 기반 문자열은 다음과 같다:

GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal
목록으로