"암시 적"흐름이 제대로 작동 할 때 OAuth2에 "인증 코드"흐름이있는 이유는 무엇입니까?


264

"암시 적"플로우를 사용하면 리소스 소유자 (예 : 사용자)가 액세스 권한을 부여한 후 클라이언트 (브라우저 등)가 액세스 토큰을받습니다.

그러나 "인증 코드"흐름을 사용하면 클라이언트 (일반적으로 웹 서버)는 리소스 소유자 (예 : 사용자)가 액세스 권한을 부여한 후에 만 ​​인증 코드를받습니다. 이 인증 코드를 사용하여 클라이언트는 액세스 토큰을 얻기 위해 인증 코드와 함께 client_id 및 client_secret을 전달하는 API를 다시 호출합니다. 여기에 잘 설명되어 있습니다 .

두 흐름 모두 결과는 동일합니다 : 액세스 토큰. 그러나 "암시 적"흐름은 훨씬 간단합니다.

질문 : "암시 적"흐름 이음새가 양호 할 때 왜 "권한 부여 코드"흐름을 방해합니까? 웹 서버에 "암시 적"을 사용하지 않는 이유는 무엇입니까?

공급자와 클라이언트 모두에게 더 효과적입니다.



1
고마워요, 이미 읽어보세요 그래도 질문에 대답하지 않습니다.
Aron Woost

1
실제로 좋은 질문은 거의 대답하지 않았습니다. :) 아래를 참조하십시오.
니콜라스 가르니에

1
@AronWoost 서버 웹 앱과 브라우저 앱을 오해한다고 생각합니다
onmyway133

@ 엔트로피 그것은 내 질문이었다; 서버에 브라우저 흐름을 사용하지 않는 이유는 무엇입니까?
Aron Woost

답변:


293

tl; dr : 보안상의 이유 때문입니다.

OAuth 2.0은 다음 두 가지 기준을 충족하려고했습니다.

  1. 모든 개발자가 SSL을 지원하는 서버를 가지고 있지는 않으며 개발자가 항상 올바르게 구성하지 않은 경우 (비 자체 서명, 신뢰할 수있는 SSL 인증서, 동기화 된 서버 시계 ...)로 인해 개발자가 비 HTTPS 리디렉션 URI를 사용하도록 허용하려고합니다.
  2. 해커가 요청을 가로 채서 액세스 / 갱신 토큰을 훔치기를 원하지 않습니다.

아래 세부 사항 :

암시 적 흐름은 보안상의 이유로 브라우저 환경에서만 가능합니다.

에서 암시 흐름 해시 단편 (안 등의 URL 파라미터)로 직접 전달되는 토큰 액세스. 해시 조각의 중요한 점 중 하나는 해시 조각이 포함 된 링크를 따라 가면 브라우저 만 해시 조각을 인식한다는 것입니다. 브라우저는 해시 조각을 대상 웹 페이지 (리디렉션 URI / 클라이언트 웹 페이지)로 직접 전달합니다. 해시 조각에는 다음과 같은 속성이 있습니다.

  • 이들은 HTTP 요청의 일부가 아니므로 서버에서 읽을 수 없으며 중개 서버 / 라우터에서 인터셉트 할 수 없기 때문에 중요합니다.
  • 클라이언트 측 브라우저에만 존재하므로 해시 조각을 읽는 유일한 방법은 페이지에서 실행되는 JavaScript를 사용하는 것입니다.

이를 통해 중개 서버가이를 가로 챌 위험없이 액세스 토큰을 클라이언트로 직접 전달할 수 있습니다. 이것은 가능한 클라이언트 측이라는 단점이 있으며 액세스 토큰을 사용하려면 클라이언트 측을 실행하는 javascript가 필요합니다.

암시 적 흐름에는 또한 예를 들어 해결 / 피할 수있는 추가 논리가 필요한 보안 문제가 있습니다.

  • 공격자는 다른 웹 사이트 / 앱의 사용자 (다른 웹 사이트 / 앱의 소유자 인 경우)에서 액세스 토큰을 가져 와서 웹 사이트에 토큰을 기록한 다음 웹 사이트의 URL 매개 변수로 전달할 수 있습니다. 따라서 웹 사이트에서 사용자를 가장합니다. 이를 피하려면 액세스 토큰과 관련된 클라이언트 ID를 확인하고 (예를 들어 Google의 경우 tokeninfo 엔드 포인트를 사용하여) 고유 한 클라이언트 ID로 토큰이 발행되었는지 (예 : 자체 앱으로) 서명을 확인해야합니다. IDToken을 사용하는 경우 (그러나 클라이언트 암호가 필요함)
  • 인증 요청이 자신의 속성 (세션 수정 공격이라고 함)에서 시작되지 않은 경우이를 방지하려면 웹 사이트에서 임의의 해시를 생성하고 쿠키에 저장 한 다음 상태 URL 매개 변수에 동일한 해시를 전달해야합니다. 인증 요청은 사용자가 돌아올 때 쿠키로 상태 매개 변수를 확인하며 일치해야합니다.

에서 인증 코드 흐름 은 URL 매개 변수 따라서 어떤 중간 서버 / 요청이 통과 만들 수있는 라우터 (수백 될 수 있음) 할 수있을 수있는 HTTP 요청의 일부이기 때문에 URL 매개 변수에 직접 액세스 토큰을 통과 할 수 없습니다 중간자 (Man-in-the-middle) 공격을 허용하는 암호화 된 연결 (HTTPS)을 사용하지 않는 경우 액세스 토큰을 읽으십시오.

이론적으로 URL 매개 변수로 액세스 토큰을 전달하는 것은 가능하지만 인증 서버는 리디렉션 URI가 TLS 암호화 및 '신뢰할 수있는'SSL 인증서 (일반적으로 무료가 아닌 인증 기관에서)와 함께 HTTPS를 사용하고 있는지 확인해야합니다. 대상 서버가 합법적이고 HTTP 요청이 완전히 암호화되어 있는지 확인하십시오. 모든 개발자가 SSL 인증서를 구매하고 도메인에서 SSL을 올바르게 구성하게하는 것은 큰 고통이 될 것이며 채택 속도가 엄청나게 느려질 것입니다. 그렇기 때문에 합법적 인 수신자 만 교환 할 수 있고 (클라이언트 비밀이 필요하기 때문에) 암호화되지 않은 트랜잭션에 대한 요청을 가로채는 잠재적 해커에게는이 코드가 쓸모가 없게됩니다. (그렇기 때문에

또한 암시 적 흐름이 덜 안전하다고 주장 할 수 있습니다. 예를 들어 클라이언트 웹 사이트의 IP 주소를 가로 채서 경로 재 지정시 도메인 스푸핑과 같은 잠재적 공격 경로가 있습니다. 이는 암시 적 플로우가 액세스 토큰 (시간 제한이있는 것으로 간주 됨) 만 부여하고 토큰 (시간 무제한)을 새로 고치지 않는 이유 중 하나입니다. 이 문제를 해결하려면 가능할 때마다 HTTPS 사용 서버에서 웹 페이지를 호스팅하는 것이 좋습니다.


12
이 두 가지 요청을 @AndyDufresne하는 HTTPS를 통해 수행해야 (필수) 그들은 요청 때문에 HTTPS 만 지원해야하는 OAuth를 서버. HTTPS를 지원할 필요가없는 것은 클라이언트 / 요청자 서버뿐이므로 Auth CodeHTTP를 통해서만 명확하게 전송됩니다. 그러나 Auth Code클라이언트 ID / 비밀이 없으면 쓸모가 없습니다. 기본적으로 OAuth 코드 흐름의 요점은 SSL 사용 서버를 갖는 부담이 API 사용자 (사용자, 본인)가 아니라 OAuth 제공자 (Google / Facebook 등)에 있다는 것입니다.
니콜라스 가르니에

5
이제 인증 코드가 일반 HTTP를 통해 전달 될 수 있으며 스니핑 될 위험이 있습니다. 인증 서버는 코드를 한 번만 사용하고 액세스 토큰을 교환하기 위해 클라이언트 시크릿을 승인하면 중간자 공격을 막을 수 있습니다. 그러나 이것은 액세스 토큰에도 적용되지 않습니까? API 사용자는 일반 HTTP를 사용할 수 있으므로 해커가 액세스 토큰을 스니핑 할 위험이 있습니까? 추신-이 글이 활성화 된 이후 오랜 시간이 지난 후에도 개념을 설명하는 데 감사드립니다. 감사 !
Andy Dufresne

8
no pb :) API에 대한 요청 (액세스 토큰이 유선을 통해 전송되어 요청을 승인하는 경우)도 HTTPS를 통해 요청됩니다. 이론적으로 클라이언트는 절대로 일반 HTTP로 액세스 토큰을 통해 전송 토큰을 보내지 않아야합니다.
Nicolas Garnier

5
이 단계의 액세스 토큰은 클라이언트에서 리소스 서버로의 HTTPS 요청 응답의 일부입니다. 이 응답은 여전히 ​​암호화되어 있습니다.
니콜라스 가르니에

13
기본적으로 클라이언트에서 자원 서버로 시작된 요청은 HTTPS를 통해 수행됩니다 (자원 소유자 서버가 HTTPS 지원을 지원해야하기 때문에). 클라이언트 서버가 HTTPS를 지원하지 않기 때문에 HTTP를 통해 수행 될 수있는 다른 곳에서 클라이언트로 시작된 요청 일뿐입니다. 예를 들어 사용자가 gant 페이지에서 권한을 부여한 후 인증 흐름 중에 발생하는 리디렉션은 브라우저에서 클라이언트 서버로 시작된 리디렉션이며 HTTP로 수행 될 수 있습니다.
니콜라스 가르니에

8

암시 적 흐름은 아주 쉽게 전체의 흐름을 만드는뿐만 아니라 안전하지 .
일반적으로 브라우저 내에서 실행되는 JavaScript 인 클라이언트 응용 프로그램은 신뢰도가 낮으므로 오래 액세스하기위한 새로 고침 토큰이 반환되지 않습니다.
사용자 데이터에 임시로 액세스해야하는 (몇 시간) 응용 프로그램에이 흐름을 사용해야합니다.
JavaScript 클라이언트에 액세스 토큰을 반환한다는 것은 브라우저 기반 응용 프로그램이 특별한주의를 기울여야한다는 것을 의미합니다. 다른 시스템으로 액세스 토큰을 유출 할 수있는 XSS 공격을 생각하십시오.

https://labs.hybris.com/2012/06/05/oauth2-the-implicit-flow-aka-as-the-client-side-flow


XSS 취약점이있는 경우 인증 코드 흐름조차 큰 도움이되지 않을 것으로 기대합니다. 그러나 암시 적 흐름에서 액세스 토큰이 자바 스크립트로 전달되는 방식이 표준화되어 (해시 조각으로) 웹 사이트에 XSS 취약점이 있으면 URL 해시에서 액세스 토큰을 읽는 공격을 구성한다는 데 동의합니다 조각은 매우 쉽습니다. 반면 인증 코드 흐름을 사용하면 사이트 간 요청 위조가 가능할 수 있습니다.
Marcel

또한 크로스 사이트 스크립팅에 관한 것이 아닙니다. 웹 사이트에서 실행되는 모든 JavaScript 라이브러리는 액세스 토큰 (예 : 타사 CDN 라이브러리 또는 Javascript 프레임 워크에서 사용하는 오픈 소스 라이브러리)을 훔칠 수 있습니다.
Marcel

2
XSS는 컨텐츠 보안 정책 헤더 및 SRI (Sub Resource Integrity) 해시가있을 때 큰 문제가되지 않습니다.
Sergey Ponomarev

4

로부터 의 OAuth 사양 :

4.2. 암시 적 보조금

암시 적 부여 유형은 액세스 토큰을 얻는 데 사용되며 (새로 고침 토큰의 발행을 지원하지 않음) 특정 리디렉션 URI를 작동하는 것으로 알려진 공용 클라이언트에 최적화되어 있습니다. 이러한 클라이언트는 일반적으로 JavaScript와 같은 스크립팅 언어를 사용하여 브라우저에서 구현됩니다.

이는 리디렉션 기반 흐름이므로 클라이언트는 리소스 소유자의 사용자 에이전트 (일반적으로 웹 브라우저)와 상호 작용할 수 있어야하고 권한 부여 서버에서 리디렉션을 통해 들어오는 요청을받을 수 있어야합니다.

클라이언트가 별도의 권한 부여 요청과 액세스 토큰을 요청하는 권한 부여 코드 부여 유형과 달리 클라이언트는 권한 부여 요청의 결과로 액세스 토큰을받습니다.

내재적 부여 유형에는 클라이언트 인증이 포함되지 않으며 자원 소유자의 존재 및 경로 재 지정 URI의 등록에 의존합니다. 액세스 토큰은 리디렉션 URI로 인코딩되므로 리소스 소유자 및 동일한 장치에있는 다른 응용 프로그램에 노출 될 수 있습니다.

우리가 고려할 수있는 것 :

  1. 이것은 공개 OAuth를위한 것입니다. 즉, 클라이언트를 등록 할 필요가없고 자체 클라이언트 시크릿이없는 경우입니다. 그러나 인증 서버가 리디렉션 URL을 확인하는 것은 실제로 보안에 충분합니다.

  2. 액세스 토큰은 브라우저의 주소 표시 줄에서 발생하므로 사용자는 URL을 복사하여 다른 사람에게 보낼 수 있으며 사용자로 기록됩니다. 즉 세션 고정과 같습니다. 그러나 브라우저는 히스토리를 대체하여 URL에서 해시 조각을 제거하여 추가 리디렉션을 수행합니다. 해커가 HTTP 트래픽을 스니핑하여 액세스 토큰을 훔칠 수도 있지만 HTTPS로 쉽게 보호 할 수 있습니다. 일부 악성 브라우저 확장 프로그램은 주소 표시 줄에서 URL에 액세스 할 수 있지만 HTTPS 인증서가 깨지는 것과 같은 최악의 상황입니다. 그리고 인증 코드 흐름조차도 여기에 도움이되지 않습니다. 그래서 내가 볼 수있는 것은 URL의 해시 조각을 통해 액세스 토큰을 전달하는 것이 절대적으로 안전하다는 것입니다.

  3. 임시 액세스 토큰과 새로 고침 토큰을 분리하는 것은 HTTPS를 사용할 때 쓸모가 없으며 원시 HTTP에서도 그렇게 유용하지 않습니다. 그러나 암시 적 흐름을 통한 클라이언트가 새로 고침 토큰을받을 수 없다는 사실도 말이되지 않습니다.

따라서 https를 통해 엄격하게 작동하고 새로 고침 토큰을 허용하거나 전혀 제거해야하며 Auth Cose 부여 흐름보다 선호되는 새로운 부여 흐름 "안전한 암시 적"을 도입해야한다고 생각합니다.


3

우리를 위해 고객은 휴대 전화에서 앱으로 한 번 인증 할 수 있기를 원했으며 한 번에 몇 주 동안 다시 로그인 할 필요가 없었습니다. 코드 흐름을 통해 액세스 토큰과 함께 새로 고침 토큰을 얻습니다. 암시 적 흐름은 새로 고침 토큰을 제공하지 않습니다. 액세스 토큰의 만료는 비교적 짧지 만 새로 고침 토큰은 최대 90 일까지 만료 될 수 있습니다. 액세스 토큰이 만료 될 때마다 클라이언트 및 서버 코드는 해당 새로 고침 토큰을 사용하여 사용자 개입없이 새로운 액세스 토큰과 새로 고침 토큰을 모두 사용할 수 있습니다. 새로 고침 토큰은 한 번만 사용할 수 있습니다. 암시 적 흐름으로는이 작업을 수행 할 수 없습니다. 암시 적 흐름을 사용하고 있고 사용자가 한 시간 이상 앱과 상호 작용하지 않으면 다시 돌아올 때 다시 로그인해야합니다. 우리의 유스 케이스에서는 허용되지 않았습니다.

새로 고침 토큰을 취소 할 수 있기 때문에이 방법이 안전합니다. 고객이 휴대 전화 나 랩톱을 분실했거나 해커가 데스크톱을 사용한다고 말하면 해당 사용자에 대한 모든 새로 고침 토큰을 취소 할 수 있습니다. 전체 프로세스 중에 개인 식별 정보 (PII)가 코드에 닿지 않습니다. 즉, 사용자의 비밀번호입니다.

코드 흐름은 훌륭하지만 더 많은 작업이 필요합니다. MS는 현재 처리 할 수있는 Angular 라이브러리가 없으므로 작성해야했습니다. 관심이 있으시면 도와 드리겠습니다.


2

내 대답은 : 당신은 웹 응용 프로그램 서버로 안전하고 간단한 방식으로 암시 적 흐름을 구현할 수 없습니다.

웹 응용 프로그램 인증 프로세스에는 사용자 상호 작용이 포함되므로 Authentication Server는 사용자 인증 및 동의 후 사용자의 브라우저를 웹 응용 프로그램의 대상 페이지로 다시 리디렉션 해야합니다 (일부 상호 작용 후 사용자를 웹 응용 프로그램으로 다시 전달하는 다른 방법은 보이지 않습니다) 인증 서버).

따라서 리디렉션 URL을 사용하여 토큰을 웹앱에 전달해야합니다.

@NicolasGarnier가 그의 답변과 의견에서 설명했듯이 토큰을 URL 조각으로 전달할 수있는 방법이 없습니다-웹 응용 프로그램 서버에 도달하지 않습니다.

또한 리디렉션 URL의 URL 매개 변수로 토큰을 전달하는 것은 HTTPS에서도 안전하지 않습니다. 대상 페이지 ( "인사말 페이지"라고 함)에 리소스 (이미지, 스크립트 등)가 포함 된 경우이 리소스는 브라우저를 통해 시리즈를 통해 가져옵니다. HTTP 요청 ( RefererURL 매개 변수를 포함하여 "인사말 페이지"의 정확한 URL을 포함하는 HTTP 헤더가 있음) 이것이 토큰이 유출되는 방식입니다.

따라서 리디렉션 URL에 토큰을 전달할 방법이없는 것 같습니다. 그렇기 때문에 두 번째 호출 (인증 서버에서 클라이언트로 (또는 어떤 URL로) 또는 클라이언트에서 인증 서버로 (인증 코드 흐름에서 두 번째 호출))

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.