공개 REST API에 대한 OAuth2 ROPC 및 기본 인증?


21

여기서 관심이있는 특정 사용 사례는 공개적으로 사용 가능한 서버 엔드 포인트 (예 : 공개 REST API)에 대해 REST 클라이언트를 인증하는 것입니다.

가장 간단한 해결책은 기본 인증 입니다. 그러나 OAuth2가 거의 모든 상황에서 우수한 인증 솔루션으로 선전되는 경우가 종종 있습니다.

건은,입니다 지내는 서버에 대해 REST 클라이언트 인증을 위해 가능하다 OAuth2를 부여 유형이 자원 소유자 암호 자격 증명 (ROPC) , 코드 보조금 및 암시 적 보조금은 대한합니다 (인증 서버에서 호스팅)는 UI / 웹 페이지를 필요로하기 때문에 사용자가 클라이언트 앱에 로그인하여 수동으로 인증합니다.

ROPC의 작동 방식은 리소스 소유자의 사용자 이름 / 암호 및 클라이언트 ID를 쿼리 문자열 매개 변수 ?!? 로 보내는 것 입니다. 최소한 base-64는 신임 정보를 인코딩하고이를 TLS로 암호화 할 수있는 헤더로 전송하는 Basic Auth보다 덜 안전합니다 (IMHO).

그래서 나는 묻습니다 : 공개 REST API의 맥락에서 OAuth2 ROPC는 실제로 Basic Auth보다 낫습니까? OAuth2 ROPC보다 안전한 것은 무엇입니까?


최신 정보

방금 AWS의 비 OAuth2 기반 REST 보안을 설명하는 이 훌륭한 기사 를 읽었습니다 . 본질적으로 각 REST 요청의 해시가 생성되어 일반 (암호화되지 않은) 요청과 함께 사이드카로 전송되는 개인 키 기반 솔루션입니다. 클라이언트와 서버 만이 개인 키를 알고 있으므로 서버가 요청을 받으면 (일반 요청 + 해시 요청 포함) 서버는 클라이언트의 개인 키를 찾고 동일한 요청을 일반 요청에 적용합니다. 그런 다음 두 해시를 비교합니다.

이것은 OAuth2의 ROPC보다 훨씬 복잡하고 복잡하며 안전합니다! 내가 뭔가를 누락하지 않는 한 주요 여기, OAuth2를 ROPC은 보내고 client_id, username그리고 password완전히와 완전히 안전하지 않은 ... 쿼리 문자열 PARAMS로! 이 HMAC / 해시 기반 솔루션은 훨씬 더 인상적이고 안전한 것으로 보입니다.

그 기사의 저자조차도 다음과 같이 말합니다.

당신은 또한 어느 시점에서 OAuth를 구현해야한다는 것을 천천히 깨닫고 받아 들일 것입니다 ...

바 바바 무트?!?! OAuth2 가이 영리한 HMAC / 해시 기반 솔루션 보다 안전 하지 않은 경우,이 기사의 저자가 OAuth를 어느 시점에 수용해야한다고 생각하는 이유는 무엇입니까? 난 너무 혼란 스러워요.


어떤 종류의 고객에 대해 이야기하고 있습니까? 대부분의 클라이언트에 UI가 있다고 가정합니다. 이 경우 OAuth 로그인 페이지를 웹뷰 (데스크톱, 모바일)에로드하거나 직접 웹 (웹)으로 리디렉션 할 수 있습니다. 왜 UI를 피해야하는지 모르겠습니다.
decyclone

@decyclone 질문에 대한 첫 번째 문장을 읽으십시오! REST 서비스에 대해 인증하는 REST (headless HTTP) 클라이언트를 사용하고 있습니다.
smeeb

내가 묻는 질문은 해당 클라이언트에 UI가 있는지 여부입니다. 그렇지 않은 경우에도 UI가없는 응용 프로그램은 최소한 인증을위한 대화 상자를 표시합니다.
Decyclone

UI는 일반적으로 REST 서비스에 연결하기 위해 순수한 REST 클라이언트를 사용하지만 @decyclone은 순수한 REST 클라이언트가 전혀 UI를 갖지 않습니다. 사용 사례 중 하나는 REST 클라이언트를 사용하여 쉘에 입력 된 사용자 명령을 REST 서비스로 보내는 명령 행 도구입니다. 쉘에서 UI를 파는 것은 여기에서 허용되는 해결책이 아닙니다.
smeeb

1
그러나 명령 줄 / 셸 외부에 다른 사용 사례가 많이 있습니다. 또 다른 사용 사례는 UI가없고 UI가없는 백엔드 서버에서 실행될 수있는 Java / Ruby / Python 순수 REST / HTTP 클라이언트입니다. 백엔드 서버는 REST를 통해 다른 백엔드 서버와 통신해야합니다. 백엔드 서버 # 1이 백엔드 서버 # 2와 대화해야 할 때 UI를 팝업하는 것은 어색하고 해킹 일뿐 만 아니라 실제 문제 는 로그인 페이지를 표시 할 브라우저 / UI 클라이언트가 없으며 사람이 없다는 것입니다. 거기에 로그인하는 것! !!
smeeb

답변:


24

질문에 대한 답변은 코드 수준, 프로토콜 수준 또는 아키텍처 수준 일 수 있습니다. 여기에서는 일반적으로 장단점 분석에서 중요한 프로토콜 수준 문제를 대부분 요약하려고합니다. 있다는 사실을 숙지 OAuth2를이 훨씬 더보다 자원 소유자 암호 자격 증명 의 사양에 따라, "레거시 또는 마이그레이션 이유"존재 "다른 교부금 유형보다 높은 위험"으로 간주하고 사양이 명시 적으로 언급되는 클라이언트와 인증 서버 "이 보조금 유형의 사용을 최소화하고 가능할 때마다 다른 보조금 유형을 활용해야합니다."

기본 인증에 비해 ROPC를 사용하는 것에는 여전히 많은 장점이 있지만 그 전에 들어가기 전에 OAuth2와 기본 인증의 기본 프로토콜 차이점을 이해하겠습니다. 이에 대해 설명하고 나중에 ROPC에 올 예정입니다.

사용자 인증 흐름

OAuth2 사양에는 4 가지 역할이 정의되어 있습니다. 예를 들면 다음과 같습니다.

  1. 자원 소유자 : 일부 자원에 액세스 할 수있는 사용자 (예 : 사용자의 경우 다른 사용자가 REST API에 대한 액세스 레벨이 다를 수 있음)
  2. 클라이언트 : 일반적으로 사용자가 사용하는 응용 프로그램이며 사용자에게 서비스를 제공하기 위해 리소스에 액세스해야합니다.
  3. 리소스 서버 : 귀하의 경우 REST API; 과
  4. 권한 부여 서버 : 사용자의 자격 증명이 제공되고 사용자를 인증 할 서버입니다.

클라이언트 응용 프로그램이 실행되면 사용자를 기반으로 리소스에 액세스 할 수 있습니다. 사용자에게 관리자 권한이있는 경우 REST API에서 사용자가 사용할 수있는 자원 및 조작은 관리자 권한이없는 사용자보다 훨씬 많을 수 있습니다.

OAuth2는 또한 여러 클라이언트와 여러 자원에 단일 권한 서버를 사용할 수 있습니다. 예를 들어, 리소스 서버는 Facebook을 통해 사용자의 인증을 수락 할 수 있습니다 (이 경우 인증 서버 역할을 할 수 있음). 따라서 사용자가 응용 프로그램 (예 : 클라이언트)을 실행하면 사용자를 Facebook으로 보냅니다. 사용자는 자신의 자격 증명을 Facebook에 입력하고 클라이언트는 리소스 서버에 제공 할 수있는 "토큰"을 다시받습니다. 리소스 서버는 토큰을보고 Facebook이 실제로 토큰을 발급했는지 확인한 후 토큰을 수락하고 사용자가 리소스에 액세스 할 수 있도록 허용합니다. 이 경우 클라이언트는 사용자의 자격 증명 (예 : Facebook 자격 증명)을 볼 수 없습니다.

그러나 이미 클라이언트에게 토큰을 부여하는 Facebook 대신 사용자 ID를 관리하고 인증 서버를 가지고 있다고 가정 해 봅시다. 이제 파트너가 있고 해당 애플리케이션 (예 : 클라이언트)이 REST API에 액세스하도록 허용하려고한다고 가정하십시오. 기본 인증 (또는 ROPC)을 통해 사용자는 해당 클라이언트에 자격 증명을 제공하여 인증 서버로 보냅니다. 그런 다음 권한 부여 서버는 클라이언트가 리소스에 액세스하는 데 사용할 수있는 토큰을 제공합니다. 불행히도 이것은 사용자의 자격 증명이 해당 클라이언트에게도 표시됨을 의미합니다. 그러나 파트너의 응용 프로그램 (조직 외부에있을 수있는 응용 프로그램)이 사용자의 암호를 알기를 원하지 않습니다. 그것은 지금 보안 문제입니다. 그 목표를 달성하기 위해

따라서 OAuth2를 사용하면 이러한 경우 ROPC를 사용하지 않는 것이 좋으며 인증 코드 흐름과 같은 다른 것을 사용하는 것이 좋습니다. 이는 권한 서버에만 제공되는 사용자의 신임 정보를 응용 프로그램이 알 수 없도록합니다. 따라서 사용자의 자격 증명이 유출되지 않습니다. 기본 인증에서도 동일한 문제가 적용되지만 다음 섹션에서는 클라이언트가 지속적인 액세스를 위해 사용자의 자격 증명을 ROPC에 저장하지 않아도되기 때문에 ROPC가 더 나은 방법을 설명합니다.

사용자가 권한 부여 서버로 이동하면 권한 부여 서버는 사용자에게 클라이언트가 자신을 대신하여 리소스에 액세스 할 수 있도록할지 확인하도록 요청할 수도 있습니다. 클라이언트가 리소스에 액세스 할 수있는 권한을 부여하는 프로세스가 프로세스에 수반되므로 권한 서버 라고합니다 . 사용자가 클라이언트를 인증하지 않으면 리소스에 액세스 할 수 없습니다. 마찬가지로, 사용자 자신이 자원에 액세스 할 수없는 경우 권한 서버는 여전히 액세스를 거부하고 토큰을 발행하지 않을 수 있습니다.

기본 인증에서는 권한 부여 서버 및 자원 서버조차 단일 엔티티로 결합됩니다. 따라서 리소스 서버는 사용자에게 권한을 부여하려고하므로 클라이언트에게 자격 증명을 요청합니다. 클라이언트는 리소스 서버가 사용자를 인증하는 데 사용하는 자격 증명을 제공합니다. 이는 여러 리소스 서버가 본질적으로 사용자의 자격 증명을 요구한다는 것을 의미합니다.

토큰 발행

클라이언트는 권한 부여 서버에서 토큰을 가져 와서 유지하고이를 사용하여 리소스에 액세스합니다 (아래 토큰 자체에 대한 자세한 내용). 클라이언트는 사용자의 비밀번호 (ROPC 이외의 플로우)를 절대 알지 못하므로 저장할 필요가 없습니다. ROPC에서 클라이언트는 사용자의 비밀번호를 알고 있지만 이러한 토큰을 사용하여 리소스에 액세스하기 때문에 여전히 비밀번호를 저장할 필요가 없습니다. 반대로 기본 인증에서 클라이언트가 모든 세션에서 사용자에게 자격 증명을 제공하지 않도록하려면 클라이언트가 다음 번에이를 제공 할 수 있도록 사용자의 암호를 저장해야합니다. 이는 클라이언트가 웹 응용 프로그램 인 경우가 아니라면 쿠키가 이러한 문제 중 일부를 해결할 수있는 경우가 아니라면 기본 인증 사용의 주요 단점입니다. 기본 응용 프로그램에서는 일반적으로 옵션이 아닙니다.

토큰이 발행되고 작동하는 방식에 수반되는 OAuth2의 또 다른 측면이 있습니다. 사용자가 인증 서버에 자격 증명을 제공하면 (ROPC에서도) 인증 서버는 두 가지 유형의 토큰 중 하나 이상을 제공 할 수 있습니다. 1) 액세스 토큰 및 2) 새로 고침 토큰.

액세스 토큰은 리소스 서버로 전송되며, 리소스 서버는 유효성을 검사 한 후 리소스에 대한 액세스 권한을 부여하며 일반적으로 수명이 짧습니다 (예 : 1 시간). 새로 고침 토큰은 클라이언트가 인증 서버로 전송하여 만료 될 때 다른 액세스 토큰을 가져 오며 일반적으로 수명이 깁니다 (예 : 며칠에서 몇 달 또는 몇 년).

클라이언트가 리소스 서버에 액세스 토큰을 제공하면 토큰을 확인하고 유효성 검사 후 토큰 내부를 확인하여 액세스 허용 여부를 결정합니다. 액세스 토큰이 유효한 한 클라이언트는 계속 사용할 수 있습니다. 사용자가 응용 프로그램을 닫고 다음 날 시작하면 액세스 토큰이 만료되었다고 가정합니다. 이제 클라이언트는 권한 부여 서버를 호출하고 만료되지 않았다고 가정하면 새로 고침 토큰을 제공합니다. 권한 부여 서버는 이미 토큰을 발행 했으므로이를 확인하고 사용자가 신임 정보를 다시 제공 할 필요가 없으므로 클라이언트에 다른 액세스 토큰을 제공함을 판별 할 수 있습니다. 클라이언트는 이제 자원 서버에 다시 액세스 할 수 있습니다. 이는 일반적으로 Facebook 및 Twitter 용 클라이언트 응용 프로그램에서 자격 증명을 한 번 요청한 다음 사용자가 자격 증명을 다시 제공하지 않아도되는 방식입니다. 이러한 응용 프로그램은 사용자 자격 증명을 알 필요는 없지만 사용자가 응용 프로그램을 시작할 때마다 리소스에 액세스 할 수 있습니다.

이제 사용자는 인증 서버 (예 : Facebook 사용자 프로필)에 들어가서 클라이언트 응용 프로그램에 영향을주지 않고 암호를 변경할 수 있습니다. 그들은 모두 제대로 작동합니다. 사용자가 이미 새로 고침 토큰이있는 응용 프로그램이있는 장치를 잃어버린 경우, 권한 부여 서버 (예 : Facebook)가 기존 응용 프로그램을 존중하지 않음으로써 수행 할 응용 프로그램에서 "로그 아웃"하도록 권한 부여 서버 (예 : Facebook)에 알릴 수 있습니다. 토큰을 새로 고치고 사용자가 해당 애플리케이션을 통해 리소스에 액세스하려고 할 때 자격 증명을 다시 제공하도록합니다.

JWT 는 단순히 OAuth2 및 OpenID Connect와 함께 사용되는 토큰 형식입니다. 토큰에 서명하고 유효성을 검사하는 방법은 또 다른 솔루션을 구현하는 모든 리소스 서버 대신 사용할 수있는 라이브러리로 표준화됩니다. 따라서, 검증 된 코드는 계속 재사용되고 지원되는 코드의 재사용 가능성이 장점입니다.

보안 영향

위 시나리오 중 하나라도 그림에 표시되면 기본 인증이 약해집니다. 또한 구현시 일반적인 취약점을 피하기 위해 제안을 사용할 수있는 개발자가 사용할 수 있는 광범위한 OAuth2 위협 모델이 있습니다. 위협 모델을 살펴보면 많은 구현 관련 취약점 (예 : 개방형 리디렉터 및 CSRF)도 포함되어 있음을 알 수 있습니다. 이 응답에서 기본 인증과 비교했습니다.

OAuth2의 마지막 주요 장점은 프로토콜이 표준화되어 있고 여러 권한 서버, 클라이언트 및 자원 서버가이를 존중한다는 것입니다. 개발자가 수많은 라이브러리를 사용할 수 있으며, 구현시 보안 문제가 발견되고 라이브러리는 상호 운용성을 유지하면서 업데이트됩니다.

결론

새로운 응용 프로그램 인 IMO를 작성하는 경우 기본 인증과 ROPC가 고유 한 문제로 인해 발생하지 않는 것이 가장 좋습니다. 그러나 각 응용 프로그램마다 요구 사항, 일정, 개발자 숙련도 등이 다르므로 결정은 사례별로 다릅니다. 그러나 기본 인증보다 더 이상 필요하지 않은 경우에도 인증을 선택하면 확장하기 쉽지 않은 아키텍처에 자신을 고정시킬 수 있습니다 (예 : 미래에 여러 서버가있는 경우에는 사용자는 인증 서버에 한 번만 제공하는 것이 아니라 토큰 등을 나눠 줄 수 있습니다.)

자격 증명이 TLS 또는 유사한 프로토콜을 사용하여 보안을 유지하거나 소유 증명 등을 통해 전송 될 수 있기 때문에 자격 증명을 전송하는 방법에 대한 귀하의 의견은 다루지 않았습니다. 이미 제안했듯이 base 64 인코딩은 0 보안입니다. 그것에 의해 빠져 나간다. 위에서 언급 한 차이점은 일반적으로 아키텍처 수준에 있으므로 아키텍처가 구현되면 변경하기가 가장 어렵 기 때문에 내가 집중 한 부분입니다.

내가 작업하고 최근에 공개 미리보기 용으로 출시 된 서비스 인 Azure Active Directory B2C Basic 을 사용하면 타사 응용 프로그램에서 AAD를 소셜 IDP (예 : Facebook, Google 등)와 상호 운용 가능한 권한 부여 서버로 사용할 수 있습니다. 또한 사용자는 소셜 IDP를 사용하지 않고 자신의 계정을 만들 수 있으며 나중에 인증 목적으로 사용할 수 있습니다. 그와 같은 다른 서비스도 있습니다 (예 : 내가 아는 다른 서비스는 auth0입니다)개발자가 애플리케이션 및 리소스에 대한 인증 및 사용자 관리를 완전히 아웃소싱하는 데 사용할 수 있습니다. 위에서 언급 한 것과 동일한 프로토콜 특성은 개발자가 권한 서버 (AAD), 리소스 (예 : REST API), 클라이언트 (예 : 모바일 애플리케이션) 및 사용자를 분리하는 데 사용됩니다. 이 설명이 다소 도움이되기를 바랍니다.


광각에 감사하지만 이러한 장점 (a) letting the user agent hold just the token instead of the password, (b) allowing a password change without disrupting existing client apps, (c) allowing users log out other sessions은 토큰 인증 흐름과 관련 이 있다고 생각하지 않습니다 . 기본 인증이나 토큰 인증은 사양에서 기능 (b)와 (c)를 언급하지 않습니다. (b)와 (c)를 구현하면 모든 종류의 인증이 가능해 보입니다. 암호 (바람직하게는 해시)를 추적해야합니다. 장점 (a)는 더 넓은 범위의 암호에 달려 있습니다.
eel ghEEz

사용자 (자원 소유자)에게 외부 권한 부여 서버에 대한 자격 증명이 없지만 클라이언트 응용 프로그램에 자격 증명이있는 경우 OAuth를 어떻게 사용할 수 있습니까? 즉, 우리는 리소스 소유자 (사용자), 클라이언트 (사용자를 나타내며 사용자의 자격 증명을 포함) 및 리소스 서버를 가지고 있습니다. 리소스 서버는 어떻게 사용자를 인증하고 권한을 부여 할 수 있습니까?
Arun Avanathan

3

URL에서 GET 변수 주변의 암호화에 대해 잘못 알고 있다고 생각합니다.

요청에서 GET 변수를 볼 수있는 유일한 사람은 원래 컴퓨터와 수신 서버 ( link )입니다.

HTTPS 요청이 전송 된 도메인을 기반으로 한 DNS 조회 만 암호화되지 않습니다. 다른 모든 포트, GET 변수, 리소스 ID는 암호화됩니다.

이것에 대한 유일한 경고는 수신 서버가 전체 요청 경로를 로그 아웃 할 수는 있지만 제어 할 수 있으므로 해당 데이터를 보호 할 수는 있지만 적합하다고 생각합니다.


3

기본 인증은 REST API를 보호하는 좋은 방법이 아닙니다. 나는 이 답변에서 이유를 설명했다 .

REST API를 빌드하면 OAuth2 용어로 자원 서버 를 구현하는 것 입니다. 당신의 API가 할 필요가 모든이의 요청과 함께 전달 된 토큰 유효성을 검증이다 인증 HTTP 헤더가 유효하고 신뢰할 수있는 발급자입니다. 사용 가능한 라이브러리가없는 경우 유효성 검사를 구현하는 단계는 이 링크 를 참조하십시오 .

클라이언트가 권한 부여 서버에서 토큰얻는 방법은 클라이언트 종류에 따라 다릅니다 . 권한 부여 서버에 클라이언트를 등록 할 때 사용할 클라이언트 유형을 지정해야합니다.

웹 애플리케이션이 서버와 통신하는 경우 인증 코드 grant를 사용할 수 있습니다 . 모바일 애플리케이션 또는 JavaScript 앱과 같은 신뢰할 수없는 클라이언트 인 경우 암시 적 grant를 사용해야합니다 .

리소스 소유자와 상호 작용할 수없는 백엔드 서비스의 경우 클라이언트 자격 증명 부여를 사용할 수 있습니다 . 명령 행 도구의 경우 클라이언트 신임 정보 또는 자원 소유자 비밀번호 grant를 사용할 수 있습니다 .

그것은 당신이 사용하는 클라이언트의 종류에 달려 있습니다.

마지막으로, JWT 토큰 유효성 검증은 권한 서버와 통신 할 필요없이 자원 서버에서 발생합니다. 이는 각 클라이언트에 대한 개인 데이터를 찾아야하는 솔루션보다 확장 성이 뛰어난 아키텍처로 이어집니다.


1

안전하거나 안전하지 않습니다. 그 이상도 이하도 아닌. base64를 사용한다고해서 기본 인증 (또는 기타)이 더 안전 해지지는 않습니다.

Https와 같은 암호화 된 파이프를 사용하는 경우 암호화되지 않은 것을 보내는 데 아무런 문제가 없습니다.

OAuth를가 가지고 , 더 많은 기능을 당신이 그것을 필요로하는 경우에 그것을 사용할 수 있습니다. 뱅킹과 같은 다른 문제의 경우 기본적인 도전-응답을 사용하는 것이 좋습니다.


0

먼저 용어를 이해해야한다고 생각합니다. 비교 및 승인 - 디지털 서명

OAuth는 Authorization 에 대한 공개 표준으로 , 질문에 제공된 기사 및 세부 정보에 따라 Amazon이 수행하는 작업이 수신자 (여기서는 Amazon)가 알려진 메시지에 의해 생성되었다고 믿을만한 이유를 제공하는 유효한 디지털 서명을 생성하는 경우입니다. 발신자, 발신자가 메시지를 보낸 것을 거부 할 수 없음 ( 인증 및 부인 방지)

사용할 권한 부여 메커니즘은 사용 사례에 따라 다소 다릅니다.

아래는 StackOverflow에서 찾을 수있는 내용입니다 .

단일 필수 헤더를 계산하기 위해 매우 간단한 해싱이 필요한 기본 인증-OAuth는 의심 할 여지없이 더 비싼 인증입니다. 알아야 할 중요한 점은 두 가지 인증 메커니즘이 완전히 다른 목적으로 사용된다는 것입니다. 기본 인증은 클라이언트를 기본 애플리케이션으로 인증하기위한 것입니다. OAuth는 타사가 기본 애플리케이션에서 클라이언트 데이터에 액세스 할 수있는 권한을 부여하기위한 것입니다. 둘 다 자신의 위치를 ​​가지고 있으며 다른 하나를 선택하는 것은 구현의 특정 사용 사례에 의해 주도되어야합니다.

그리고 여기 두 가지를 비교하는 또 다른 흥미로운 기사가 있습니다.

SSL을 통한 기본 인증 은 단순한 보안 관점에서 실제로 책임이 있습니다. 우리가 사용자 이름과 암호에 대해 논쟁 할 때, Basic auth는 구현하기가 쉽기 때문에 널리 사용되는 솔루션입니다. 자격 증명 전송은 SSL을 통해 암호화되며 "Authorization"헤더 사용은 HTTP 클라이언트 및 시스템에서 어디에나 존재합니다.

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