해당 포스트는 다음 NHNFORWARD 내용을 바탕으로 작성되었습니다.
로그인에 사용하는 OAuth: 과거, 현재 그리고 미래
가장 먼저 인증과 인가가 무엇인지 알아보겠습니다. 다음과 같은 상황을 예시로 들어보겠습니다.
어느날 길을 가다가 경찰관을 길에서 만났습니다.
경찰관 : 안녕하십니까, 신원을 확인하도록 하겠습니다. 성함이 어떻게 되시나요?
나 : (지갑에 있는 신분증을주면서) , 제 이름은 홍길동입니다.
경찰관 : (신분증과 밑에 있는 직인을 확인 후 ) 홍길도이 맞군요!
이렇게 사용자의 신원을 확인하는 행위를 인증이라고 합니다.
어느날 회식에서 술을 많이 먹고 대리기사를 부릅니다.
대리운전 기사 : 제가 대리운전 서비스를 해 드리기 위해 자동차 사용 권한이 필요합니다.
나 : 제 자동차 키를 들리 테니 대리 운전해 주세요.
내가 소유하고 있는 자동차에 대한 사용 권한을 잠시 일시적으로 위임하게 됩니다. 이것을 바로 인가라고 합니다.
OAuth("Open Authorization")는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다. 이 매커니즘은 여러 기업들에 의해 사용되는데, 이를테면 아마존, 구글, 페이스북, 마이크로소프트, 트위터가 있으며 사용자들이 타사 애플리케이션이나 웹사이트의 계정에 관한 정보를 공유할 수 있게 허용한다. 위키백과
OAuth 1.0에서는 3개의 역할이 있습니다.
Resource Owner : OAuth 1.0에서는 자연인을 의미합니다. 즉, SNS에 가입하고 사진을 업로드 등 다양한 기능을 제공하는 어플리케이션에게 인가 작업을 할 수 있는 자여인을 의미합니다.
OAuth Client : Resource Owner의 리소스에 접근을 해서이 리소스를 어떤 식으로 활용을 하려고 하는 어플리케이션을 의미합니다.
OAuth Server : Resource Owner의 신분을 확인 및 인증하고 그리고 Resource Owner와 상호작용을함으로써 OAuth Client에게 역할을 인가하는 역할을 합니다.
먼저 과정은 다음과 같습니다. OAuth Client가 Resource Owner의 리소스를 사용하고 싶어합니다. 예를 들어 여기서는 SNS 사진 에디터가 Resource Owner의 사진을 사용하여 편집을 하고 싶다고 해봅시다. 그렇게 되면 OAuth Server가 인증 주소를 전달하게 되면 이 주소를 받은 OAuth Client가 다시 이 주소를 Resource Owner에게 전달합니다.
그렇게 되면 Resource Owner는 우리가 자주 보는 다음과 같은 인증을 위한 로그인 창을 볼 수 있게 됩니다. 이렇게 해서 Resource Owner는 OAuth Client에게 권한을 인가합니다.
OAuth Server는 302 리디렉트나 웹 기반 redrect를 사용을 해서 받은 인증 코드를 OAuth Client에게 넘겨주게 됩니다. 그리고 마지막으로 OAuth Client는 인증 값을 받아서 API 호출을 통해서 OS 서버로부터 인가 권한을 나타내는 토큰이라는 스트링 값을 전달 받게 됩니다. 이후로 OAuth 클라이언트는 Resorce Owner의 리소스에 접근을 하거나 어떤 서비스에 접근을 할 때이 토큰을 사용을 해서 리소스에 접근을 하게 됩니다.
보면 OAuth 1.0 프로토콜에서 OAuth Client에게 사용자의 아이디나 비밀번호 전달을 하지 않고도 인증/인가가 완료되었습니다. 하지만 OAuth 1.0 에도 문제가 있습니다.
Scope(범위) 개념의 부재: OAuth 1.0은 사용자의 권한을 제어하기 위한 Scope 개념을 제공하지 않습니다. Scope는 애플리케이션이 요청할 수 있는 리소스의 범위를 정의하는 데 사용됩니다. 따라서 OAuth 1.0에서는 애플리케이션이 사용자의 모든 권한을 요청하거나 특정한 권한만 요청하는 것 사이에 구분이 없습니다. 이는 사용자의 권한을 더 세밀하게 제어하기 어렵게 만듭니다.
역할이 확실이 나누어있지 않음: OAuth 1.0 Server의 역할은 Resource Owner 인증 , 인가 토큰 발급 , 보호된 리소스 관리(호스팅)하는 역할을 담당하면서 역할이 모호함.
토큰 유효기간 문제: OAuth 1.0은 토큰의 유효기간을 관리하는 명세가 제공되지 않았습니다. 이로 인해 토큰이 무제한으로 유효할 수 있거나, 적절한 방법으로 만료 및 갱신되지 않을 수 있습니다. 이는 보안상의 위험을 초래할 수 있으며, 애플리케이션과 사용자 간의 인증 및 권한 부여 프로세스를 더욱 취약하게 만듭니다.
Client 구현 복잡성: OAuth 1.0은 클라이언트(애플리케이션)의 구현이 복잡한 특징을 가지고 있습니다. 암호화 및 서명 절차, 요청 및 응답의 암호화 방식, Nonce 및 Timestamp 사용 등의 기술적인 요구사항들이 클라이언트 개발자에게 추가적인 부담을 주게 됩니다. 이는 애플리케이션 개발 및 유지보수의 어려움을 초래하고, 오류 발생 가능성을 높일 수 있습니다.
사용 환경 측면: OAuth 1.0은 프록시 서버 및 일부 환경에서 문제를 발생시킬 수 있습니다. 프록시 서버가 요청 및 응답을 수정하는 경우, OAuth 1.0의 서명 및 암호화 메커니즘은 오작동할 수 있습니다. 또한, 일부 네트워크 환경에서는 암호화 및 서명 절차가 제대로 작동하지 않을 수 있습니다. 즉 웹 브라우저 환경에 최적화된 프로토콜입니다.
Scope(범위)의 도입: OAuth 2.0은 Scope 개념을 도입하여 애플리케이션이 요청할 수 있는 리소스의 범위를 세밀하게 정의할 수 있게 되었습니다. 사용자의 권한을 더욱 세밀하게 제어할 수 있고, 필요한 권한만 요청하여 보다 정확한 권한 부여를 할 수 있습니다.
역할 기반 접근 제어: Resouce Owner 인증 , 인가 토큰 발급은 OAuth Server에서 진행하고 보호된 리소스 관리는 Resource Server로 분리하면서 아키택쳐를 개선함.
토큰 기반 유효기간 관리: OAuth 2.0은 토큰의 유효 기간을 관리하기 위한 명세를 제공합니다. 액세스 토큰과 리프레시 토큰을 사용하여 토큰의 만료를 관리하고, 필요한 경우 리프레시 토큰을 사용하여 액세스 토큰을 갱신할 수 있습니다. 이를 통해 토큰의 보안과 수명을 효과적으로 관리할 수 있습니다.
단순화된 프로토콜: OAuth 2.0은 프로토콜 자체를 단순화하여 구현 및 사용을 용이하게 만들었습니다. Bearer Token과 TLS를 활용하여 복잡한 암호화 및 서명 절차를 간소화하고, 개발자가 쉽게 이해하고 구현할 수 있도록 설계되었습니다.
클라이언트의 다양한 종류: OAuth 2.0은 다양한 클라이언트 유형에 대한 지원을 제공합니다. 웹 애플리케이션, 모바일 애플리케이션, 데스크톱 애플리케이션 등 다양한 환경에서 OAuth 2.0을 사용할 수 있습니다. 또한, Grant를 도입하면서 클라이언트 인증에 대한 다양한 방식을 지원하여 클라이언트의 구현 복잡성을 줄이고 유연성을 높였습니다.
OAuth 2.0에서 추가된 Grant(인가 방식)은 클라이언트가 액세스 토큰을 얻기 위해 사용하는 인증 방식을 나타냅니다. OAuth 2.0은 다양한 Grant 유형을 지원하여 다양한 클라이언트 유형 및 사용 사례에 대응할 수 있습니다. 각 Grant 유형은 클라이언트의 신원과 액세스 토큰 발급을 위한 인증 절차를 다르게 정의합니다. 여기서 네 가지 주요한 Grant 유형을 살펴보겠습니다:
Authorization Code Grant (인가 코드 방식): 이는 가장 일반적으로 사용되는 OAuth 2.0 인증 방식입니다. 웹 애플리케이션에서 주로 사용되며, 백엔드 서버를 통해 클라이언트가 액세스 토큰을 요청하는 방식입니다. 사용자는 클라이언트 애플리케이션으로부터 리다이렉트되어 인증 서버에서 로그인 및 권한 부여를 하고, 인가 코드를 받습니다. 그런 다음 클라이언트는 인가 코드와 함께 인증 서버에 액세스 토큰을 요청하고 이를 교환합니다.
Implicit Grant (암시적 방식): 이 방식은 웹 브라우저 자바스크립트 기반의 클라이언트 애플리케이션에서 사용됩니다. 리소스가 제한된 상황에서 복잡된 서버 투 서버 통신을 하기 보단 간략화된 인증방식입니다. 액세스 토큰을 직접 요청하며 인가 코드를 교환하지 않습니다. 대신, 사용자가 인증 서버에서 로그인하고 권한을 부여한 후, 클라이언트가 액세스 토큰을 받습니다. 이 방식은 간편하지만 보안성이 낮을 수 있으므로 주의해야 합니다.
Client Credentials Grant (클라이언트 자격 증명 방식): 이 방식은 클라이언트 애플리케이션이 자체적으로 액세스 토큰을 요청할 때 사용됩니다. 즉 리소스 오너와 클라이언트가 동일한 개체일 때 사용합니다. 사용자의 개인 정보와는 관련이 없으며, 클라이언트의 신원을 인증하여 액세스 토큰을 발급받습니다. 보통 서버 간 통신이 필요한 경우나 백그라운드 작업을 수행하는 서버 애플리케이션에서 사용됩니다.
Resource Owner Password Credentials Grant (리소스 소유자 암호 자격 증명 방식): 이 방식은 사용자의 로그인 정보(아이디와 비밀번호)를 사용하여 직접 액세스 토큰을 요청할 때 사용됩니다. 클라이언트가 사용자의 암호를 알고 있어야 하므로, 보안성이 높지 않을 수 있습니다. 일부 특수한 경우에만 사용되며, 일반적으로 권장되지 않습니다.
각 Grant 유형은 다른 사용 사례와 보안 요구에 맞게 선택되어야 합니다. 클라이언트 유형과 애플리케이션의 보안 요구 사항을 고려하여 적절한 Grant 유형을 선택하고 구현해야 합니다.
더 보안적으로 민감한 사용처들의 프로토콜 채택
-> RFC 보안책들을 하나로 모아 스펙화 시킨 것!
보안 강화: OAuth 2.1은 보안 측면에서 몇 가지 강화된 사항을 가지고 있습니다. OAuth 2.1은 보안 관련 취약점을 보완하고, 구현자들이 보다 안전한 방식으로 OAuth를 사용할 수 있도록 지침을 제공합니다.
간소화된 구성 요소: OAuth 2.1은 구성 요소를 간소화하고 필요한 요소에 대한 명확한 설명을 제공합니다. 몇 가지 선택 사항과 확장 요소는 제거되었으며, 구성 요소 간의 관계가 명확히 설명되어 있습니다.
범용성 강조: OAuth 2.1은 기존 OAuth 2.0의 다양한 사용 사례를 지원하며, 개발자들이 OAuth를 보다 폭넓게 사용할 수 있도록 돕습니다. 범용적인 프로토콜로서의 유연성과 사용성을 강조합니다.
더 자세한 사항은 영상 확인 부탁드립니다!