Summary
OAuth는 소통 주체가 리소스에 접근할 수 있는지 없는지에 대한 Authorization(권한 부여) 의 표준
제한된 사람(혹은 시스템)에게 제한된 권한을 어떻게 잘 부여할 것인가에 중점
Authorization: 사용자에 사용 권한을 허락해 주는 절차, 어떤 서비스에 로그인한 후에 이뤄지는 사용자의 행위에 대해 허가
OpenID 는 소통하는 주체가 누구인지에 대한 Authentication(인증) 에 대한 표준이다.
인증 시스템으로써 사용자 정보를 관리하고 인증하는 것에 초점
Authentication: 사용자가 누구인지 확인하는 절차, 회원가입 하고 로그인 하게 하는 것
사용자 인증을 통한 응답 차이
- OAuth(access token): 권한 부여 - 페이스북 posting 권한, 유저 profile view 권한 등
- OpenID(id token): 사용자 인증 및 사용자 정보 제공
액세스 토큰을 호텔 카드키에 비유, ID 토큰은 주민등록증
호텔 카드키 소유자는 어떤 객실에 출입할 권한이 있는지 알 수 있지만, 카드키 소유자에 대한 신원 정보를 전혀 알 수 없음
주민등록증은 신원확인 가능, but 호텔 객실에는 출입할 수 없음
OAuth 2.0은 리소스 서버로부터 리소스를 가져오기 위한 액세스 토큰 확보에 목적,
OpenID Connect는 사용자의 신원 정보가 담긴 ID 토큰 확보에 목적.
Oauth
위임 권한 부여를 위한 표준 프로토콜
어플리케이션이 사용자 패스워드 없이 사용자 데이터에 접근 가능하도록 허가해준다.
- 리소스 소유자(Resource Owner): 클라이언트 어플리케이션이 접근하길 원하는 데이터를 가지고 있는 사용자이다.
- 클라이언트(Client): 사용자의 데이터에 접근하고 싶어하는 어플리케이션이다.
- 권한부여 서버(Authorization Server): 사용자로부터 권한을 부여받음으로써 클라이언트가 사용자의 데이터에 접근할 권한을 부여해주는 권한부여 서버이다.
- 리소스 서버(Resource Server): 클라이언트가 접근하길 원하는 데이터를 갖고 있는 시스템이다. 때때로 권한부여 서버와 리소스 서버가 같은 경우가 있다.
- 액세스 토큰(Access Token): 리소스 서버에서 사용자에 의해 부여된 데이터에 접근하기 위해서 클라이언트가 사용할 수 있는 유일한 키가 바로 이 엑세스 토큰이다.
- 사용자가 클라이언트에 접근
- 권한부여 서버로 리다이렉트, (로그인, 약관동의). 이때 클라이언트는 권한부여 서버에 clientId, redirect_uri, scope 등 전달
- 유저가 허가 하면 권한부여 서버는 권한 부여 코드와 함께 클라이언트의 redirect_uri 로 리다이렉트 시킴
- 클라이언트는 권한 코드를 권한부여에게 엑세스 토큰으로 변경 요청하여 엑세스 토큰을 응답 받음
- 엑세스 토큰은 리소스 서버에 접근할 수 있는 유일하고 중요한 키이다.
- 이때 클라이언트는 엑세스 토큰을 브라우저에 노출시키지 않기 위해서 백 서버를 활용한다.
- 백 서버로 권한 코드를 넘기고 클라이언트 앱의 백 서버에서 권한 코드를 액세스 토큰으로 바꾼다. (client_secret이 이 때 필요함 )
- 클라이언트(그 중 백 서버)는 리소스 서버에 엑세스 토큰으로 사용자 데이터 요청
- 리소스 서버가 키의 유효성 검사 후 유저의 데이터를 클라이언트에게 전달
* scope: 클라이언트가 리소스 서버에 접근할 수 있는 제한 범위에 대한 내용
IDP
Identity Provider, 짧게 줄여서 IdP는 실제 사용자 정보를 제공해 주는 신원 제공자
ex. Google이나 Apple 등과 같은 간편 서비스를 제공하는 회사 의미
사용자가 특정 애플리케이션(또는 서비스)에 로그인하기 위해서 별도 회원가입을 거치지 않고 바로 가입 -> 로그인 -> 사용할 수 있도록 사용자의 신원 증명(또는 인증)을 해주는 것이 IdP의 주된 역할
IDP와 SP(Service Provider) 사이에는 사용자를 인증할 수 있는 증명 정보에 대한 통신이 이뤄져야 함.
-> 신원 정보 증명을 위한 통신 기술이 바로 OpenID로 대표되는 OAuth 기술(현재는 OAuth 2.0)
OpenID Connect
OpenID Connect 는 OAuth2.0을 확장하여 인증 방식을 표준화
문자 그대로 오픈된 Identity 의미, 서로 연계된 서비스 간에 사용자 인증 등을 오픈해주는 기술
-> 서비스 운영자는 안전하게 사용자 데이터를 관리할 수 있는 IdP에 사용자 인증 절차를 위임하고, 사용자는 자신이 신뢰할 수 있는 서비스의 인증 정보 하나로 여러 서비스에서 인증하게 만듬
클라이언트가 권한부여 서버에 처음 요청을 보낼 때 scope 에 openid 값이 포함되어 들어오면,
권한부여 서버는 액세스토큰과 사용자 인증에 대한 정보를 ID 토큰을 준다.
ID 토큰은 JWT 또는 JSON 웹 토큰으로 payload에 사용자 정보가 인코딩 되어 있다.
-> 따라서 트랜잭션이 1/2로 줄어들게 되어 인증의 속도가 훨씬 빨라짐 + 네트워크에 그만큼 부담 덜어줌(OpenID Connect의 등장 배경)
ID 토큰에는 iss, exp 같은 기본적인 클레임과 함께 sub라는 유저 식별 정보(ID)를 보내줌.
scope에 openid 뿐 아니라 IdP에서 제공하는 추가적인 스코프(ex. email 등)를 추가로 포함하여 요청하면 ID 토큰에 유저에 대한 추가적인 정보를 얻어올 수 있을 것.
OpenID Connect는 인증 표준 규격을 정의하는 프로토콜에 가깝고 실제 인증 및 사용자 정보 제공은 IdP를 통하여 수행 → 재밌게도 OpenID Connect에서 IdP의 역할을 OAuth가 수행
OAuth 진영에서 OAuth 기술은 Authentication 기술이 아니라고 명시한다. OAuth에서 제공해주는 access token은 특정 액션을 위해 일시적으로 권한을 허가해 준 토큰일 뿐이지 사용자에 대한 정보를 전혀 담고 있지 않다고 함. (access token을 가지고 있는 누구나 해당 권한을 사용할 수 있음.) 그렇기 때문에 access token을 발급하기 위해 사용자 인증을 거치긴 하였지만 access token 자체가 사용자 신원 정보를 대표해서는 안된다고 설명한다.
그렇다면 OpenID Connect에서는 이러한 문제를 어떻게 해결했을까?
OpenID Connect가 하고 싶은 것은 사용자 인증과 사용자 신원 정보 제공이고 OAuth가 잘하는 것은 권한을 허가해주는 일이다.
그렇다면 OpenID Connect가 OAuth에게 사용자 신원 정보를 제공해 달라고 권한을 요청하면 어떨까?!
OAuth는 OpenID Connect의 요청에 따라 사용자를 인증하고 사용자 신원 정보를 전달할 수 있을 것이다.
- 이때 “사용자 정보 제공” 권한을 openid scope, 사용자 신원 정보가 담긴 토큰을 id token 이라고 한다.
- 이해를 돕기 위해 OpenID Connect라는 컴포넌트를 그렸지만 실제로 OpenID Connect는 인증 표준 규격을 정의하는 프로토콜에 가깝고 모든 구현은 OAuth에 들어 있다. 그래서 보다 정확한 그림은 아래의 이미지가 된다.
- 마지막으로 이때 사용하는 id token의 형태는 jwt 형식을 따른다. 그렇기 때문에 IdP를 통해 생성되어 사용자로 전달된 토큰이 변조 되었는지 쿠버네티스쪽에서 쉽게 확인할 수 있음.
eBay의 예제를 통해 정리해보자.
- eBay 서비스를 이용하기 위해 'Sign in with Google' 버튼을 클릭하면 OP(Google)는 eBay 사용 시 필요한 인증화면(예: 로그인, 인증 번호 입력 등)을 내려 주게 된다. 참고로 eBay는 사전에 해당 OP를 사용하기 위해 인증이 가능하도록 등록을 마쳤으며, 필요한 client id, client secret 같은 정보들을 OP로부터 제공받은 상태.
- 인증레벨에 따라 다양한 인증방법을 요구할 수 있음. eBay는 OP로부터 발급받은 client id를 비롯해 redirect uri, scope 등의 정보로 OP에 Authorization Code(허가 코드)를 요청.
- OP는 인증 및 인가 여부를 판단하여, 1회용 Authorization Code를 eBay에 발급.
- eBay는 전달받은 코드 및 client id, client secret 등의 정보로 OP에 Access 토큰과 ID 토큰을 요청.
- OP는 Access 토큰 및 ID 토큰을 eBay로 전달.
- eBay는 Access 토큰을 이용하여 다른 RS(Resource Server) 자원들을 요청할 수 있게 됨.
위의 순서를 보면 OAuth 2.0의 흐름과 크게 달라 보이지 않는 것을 알 수 있음.
이는 서두에 언급한대로 OpenID Connect가 OAuth 2.0을 기반으로 상위계층에서 좀 더 간편하게 인증을 처리할 수 있도록 고안되었기 때문.
OpenID Connect는 Access 토큰과 함께 ID 토큰을 전달한다. 이 JWT(JSON Web Tokens)를 통해 암호화 된 토큰 안에 사용자 정보를 비롯한 다양한 정보를 HTTP 헤더의 최대 사이즈인 4KB 이내로 저장할 수 있다. 이로 인해 eBay는 Access 토큰을 사용하여 한 번 더 OAuth 2.0 API를 호출할 필요 없이 사용자 정보가 담긴 ID 토큰을 복호화 하여 바로 사용할 수 있게 된다.
단편적인 예로 5천만 명의 사용자들이 eBay를 이용할 경우, 사용자 정보를 가져오기 위해서는 최소 1억 번의 API 호출이 필요했었지만 ID 토큰을 이용하면 그 절반인 5천만 번 정도만 호출하면 된다.
참고 자료
- https://hudi.blog/open-id/
- https://www.samsungsds.com/kr/insights/oidc.html
- https://coffeewhale.com/kubernetes/authentication/oidc/2020/05/04/auth03/
- https://hudi.blog/open-id/
참고) IdP 표준
SAML 2.0 : 2001년 OASIS에서 정의한 개방형 Authentication(인증) 및 Authorization(인가) 표준이며, 엔터프라이즈 애플리케이션의 SSO(Single Sign On)를 목적으로 XML(Extensible Markup Language) 형식으로 개발
OAuth 2.0 : 2006년 Twitter와 Google이 정의한 개방형 Authorization 표준이며, API 허가를 목적으로 JSON(Javascript Object Notation) 형식으로 개발
OIDC 2.0 : 2014년 OpenID Foundation에서 정의한 개방형 Authentication 표준이며, 컨슈머 어플리케이션의 SSO를 목적으로 JSON 형식으로 개발
'Own > Memo' 카테고리의 다른 글
API 아키텍처 - REST와 RPC (0) | 2023.07.31 |
---|