OAuth 2.0 Simplified
OAuth 2.0 공식 사이트의 내용을 기반으로 인증 작업 흐름에 대한 부분을 중점으로 정리했다.
OAuth 2.0 is the modern standard for securing access to APIs.
OAuth 2.0은 API에 대한 액세스를 보호하기 위한 최신 표준이다.
Despite OAuth being an authorization protocol rather than an authentication protocol, it is often used as the basis for authentication workflows anyway. A typical use of many common OAuth APIs is just to identify the user at the computer when logging in to a third-party app.
OAuth 는 인증 프로토콜이 아닌 인가 프로토콜임에도 불구하고 인증 작업 흐름의 기반으로 자주 사용된다. 주로 OAuth API의 일반적인 사용은 타사 앱에 로그인할 때 컴퓨터에서 사용자를 식별하는 것이다.
1. Client Registration
클라이언트 등록은 개발자가 인증 서버를 사용하기 위해 개발한 애플리케이션을 등록하는 작업이다.
등록된 애플리케이션만 접근을 제한하거나 데이터에 접근을 제한하기도 한다. 네이버나 카카오 등 오픈 API 를 사용하기 위해 애플리케이션을 등록하는 기능과 같으니 참고하면 된다.
클라이언트 등록을 마치면 clientId와 clientSecret 값을 얻을 수 있다.
등록한 애플리케이션은 삭제할 수 있어야하며 최소한 비활성화 기능은 제공되어야 한다.
애플리케이션 등록에서 아래와 같은 역할을 한다.
- client_id 와 client_secret 제공
- 애플리케이션 정보 저장
- redirect url 관리
- scope 관리
애플리케이션을 등록하면 client_id 와 client_secret 값을 제공해야 한다.
- client_id
- 키값은
공개
될 수 있다 - 키값은 추측할 수 없는 32자 16진수 문자열 조합을 사용한다.
사용 예시) Foursquare: ZYDPLLBWSK3MVQJSIYHB1OR2JXCY0X2C5UJ2QAR2MAAIT5Q Github: 6779ef20e75817b79602 Google: 292085223830.apps.googleusercontent.com Instagram: f2a1ed52710d4533bde25be6da03b6e3 SoundCloud: 269d98e4922fb3895e9ae2108cbb5064 Windows Live: 00000000400ECB04
- 키값은
- client_secret
- 키값은
비공개
되어야 한다. - 키값 생성시 서버의 TimeStemp 또는 MAC 주소, UUID 라이브러리로 사용하지 않아야 한다.
- 키값 생성시 암호화 라이브러리를 사용하여 256비트 값을 생성하고 이를 16진수 표현으로 변환하여 사용한다.
- 애플리케이션에 포함되지 않아야 하며 유출되지 않도록 주의해야 한다.
- 웹 서버 애플리케이션만 발급되어야 한다.
- 공개되는 애플리케이션은 발급되면 안된다. 즉 Moblie App, SPA, Client App 등 모바일이나 브라우저 기반의 앱에 절대 포함하지 않아야 한다.
- 키값을 생성시 최초 한번만 표시하거나 쉽게 재확인할 수 없도록 보안을 강화해야 한다.
- 키값을 재발급할 수 있도록 제공되어야 한다. 재발급하더라도 사용자의 accessToken 는 무효화되지 않는 다.
- 키값은
애플리케이션을 등록하기 위해 일반적인 항목은 아래와 같다.
- 애플리케이션 이름
- 애플리케이션 아이콘
- 애플리케이션의 홈 페이지 URL
- 애플리케이션의 간단한 설명
- 리디렉션 URL
- 개인정보취급방침 URL
그 외에도 필요한 정보가 수집될 수 있다.
Redirect URL
- 허가된 리디렉션 URL을 등록하도록 요구하는 것이 중요하다.
- 리디렉션 URL은 사용자가 애플리케이션 인증 승인 후 반환되는 URL이다.
- 리디렉션 URL에 매개변수를 포함하지 않는 것이 좋다.
- https를 사용하는 것이 바람직하다.
Scope
범위는 사용자가 데이터에 접근하는 것을 제한할 수 있다. 사용자 계정에 권한을 부여하는 방법이 아닌 애플리케이션에 범위를 설정하여 데이터나 서비스에 접근하는 것을 제한하는 방법이다. 접근 범위라고 할 수 있다.
예를들어 사용자 페이지와 관리자 페이지가 있다면 A 애플리케이션은 사용자 페이지만 접근할 수 있고 B 애플리케이션은 관리자 페이도 접근할 수 있도록 제한할 수 있으며 A 애플리케이션은 인증된 사용자 정보만 접근할 수 있고 B 애플리케이션은 모든 사용자의 정보에 접근할 수 있도록 제한할 수 있다.
사용자의 정보를 애플리케이션에 제공되므로 인증 과정에서 제공되는 범위에 대해 사전 공지하고 동의를 얻어야 한다. 이 과정이 없으면 사용자는 자신도 모르게 애플리케이션에 사용자 정보가 제공될 수 있고 악의적으로 사용될 수 있다.
범위에 대해 사용자가 직접 설정할 수 있도록 사용자 편의성을 제공하기도 한다.
Client Registration에서 애플리케이션을 등록하면서 범위를 관리할 수 있어야 한다.
2. Access Token - 액세스 토큰
액세스 토큰은 애플리케이션이 사용자를 대신하여 API를 요청하는 데 사용하는 인증 토큰이다. 액세스 토큰은 애플리케이션이 특정 데이트에 접근할 수 있는 권한을 나타냅니다.
- 액세스 토큰은 해당 애플리케이션과 인증 서버, 리소스 서버에서만 사용하고 유출되지 않도록 주의한다.
- https 보안 프로포콜을 사용하는 것을 권장한다.
액세스 토큰으로 교환하기 위한 인증 방식 4가지를 설명한다.
Authorization Code - 인증 코드 방식
로그인 사용자가 코드를 취득하고 코드로 액세스 토큰을 발급 받을 수 있다. 예를들어 카카오 계정으로 통해 내가 만든 애플리케이션을 인증받을 때 사용한다.
- 사용자가 인증된 상태에서 진행할 수 있다. (즉 카카오에 로그인한 상태여야 한다)
- 애플리케이션에서 인증 서버로 인증 요청을 한다.
- 인증 서버에서 인증된 사용자가 아니면 로그인 페이지로 이동할 것이다. 인증된 사용자라면 해당 애플리케이션이 접근을 허용할 것인지 사용자가 설정할 수 있는 페이지가 제공된다.
- 사용자가 허용하면 코드를 받을 수 있다.
- 코드를 이용하여 액세스 토크를 발급 받는 다.
Implicit - 암시적 인증 방식
일반적으로 액세스 토큰을 교환하기 위해 ClientSecret 값이 필요하다. ClientSecret은 안전하게 저장되어야하며 노출되어선 안된다. 브라우저에서 구동되는 애플리케이션은 안전한 저장 공간이 없다.
그래서 자바스크립트로 개발된 SPA(단일 페이지 애플리케이션) 또는 웹 페이지에서 직접 액세스 토큰을 교환할 목적으로 사용된다.
authorization code 인증 방식과 유사하며 작업 흐름에서 인증 코드없이 액세스 토큰을 교환할 수 있다.
하지만 보안적으로 안전하다고 볼 수 없고 특별한 경우를 제외하고 다른 인증 방식을 사용하는 것을 권장한다.
refresh token을 제공하지 않으므로 사용할 수 없다.
참고: https://www.oauth.com/oauth2-servers/single-page-apps/
Password - 비밀번호 인증 방식
계정과 비밀번호를 입력하여 액세스 토큰으로 교환할때 사용한다. 자사의 통합 로그인을 구현할때 사용하고 그외 사용하지 않는 것을 권장한다. 즉 타사 애플리케이션에서 사용해서는 안된다.
Client Credentials - 클라이언트 자격 인증 방식
clientId와 clientSecret으로 액세스 토큰을 교환할 수 있다. 사용자 정보를 사용하지 않기 때문에 사용자 정보는 얻을 수 없다. 서버간에 인증을 할때 사용할 수 있다.
성공적인 응답
access token을 성공적으로 교환되면 응답 내용으로 얻을 수 있는 것은 다음과 같다.
- access_token - 인증된 액세스 토큰
- token_type - 토큰의 유형 일반적으로
bearer
이다. - expires_in - 액세스 토큰 만료일
- refresh_token - 새로고침 토큰, 항목은 선택사항이다.
- scope - 접근 범위, 항목은 선택사항이다.
위 항목은 필수적이며 선택사항은 상황에 따라 사용될 수 있다. 그외 필요한 정보는 직접 추가할 수 있다.
비밀이 보장되어야 하므로 저장소와 캐시에 저장되지 않도록 알려야 한다.
Cache-Control: no-store
Pragma: no-cache
HTTP Response Header
에 포함하도록 한다.
실패할 경우 응답에 대해서는 https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/링크에서 "실패한 응답"을 참고한다.
접근 승인된 목록 페이지
자신의 계정으로 승인된 애플리케이션을 관리할 수 있도록 제공하는 페이지이다. 승인된 애플리케이션에 접근 범위를 노출하고 승인을 취소할 수 있다.
일반적으로 세부기능은 다음과 같다.
- 승인 날짜
- 자세한 접근 범위
- 승인 취소
승인 취소
아래와 같은 사유로 승인 취소가 필요한다.
- 사용하지 않는 애플리케이션
- 애플리케이션이 더이상 운영하지 않을 때
- 애플리케이션에서 모든 승인을 취소 했을 때
- 사용자가 직접 승인 취소
인증 서버의 저장소를 경유하는 액세스 토큰은 승인 취소시 다음 자원 요청에 의해 액세스 토큰 유효성이 실패하므로 승인 취소할 수 있다.
하지만 JWT와 같은 Stateless한 액세스 토큰은 토큰 자체로 인증된 상태이므로 승인 취소는 어려움이 있다.
토큰 유효시간이 만료되기를 기다려야 하기에 만료 시간을 짧게 설정하는 이유도 있다.
승인 취소가 필요한 중요한 정보나 권한을 가진 토큰이라면 자원 요청시 항상 인증 서버를 통한 유효성 검증을 하도록 설계해야 한다.
3. Resource server
리소스 서버는 API 서버의 OAuth 2.0 용어입니다. 리소스 서버는 애플리케이션이 액세스 토큰을 얻은 후 인증된 요청을 처리합니다.
오류 응답은 HTTP Header
의 WWW-Authenticate
속성에 응답 오류를 정의하여 응답한다.
참고: https://www.oauth.com/oauth2-servers/the-resource-server/
토큰 검증 (token introspection endpoint )
리소스 서버에서 인증 서버로 액세스 토큰을 확인하기 위한 기능이다.
응답 항목은 다음과 같다.
- active - 토큰 상태를 boolean으로 응답한다.
- scope
- client_id
- username
- exp
'Tech' 카테고리의 다른 글
Spring RabbitMQ and retry and Dead Letter Queue (0) | 2021.11.03 |
---|---|
프로젝트 코드 템플릿 - Project Code Templates (0) | 2021.10.28 |
자주 사용하는 Git CLI (Command line interface) (0) | 2021.10.15 |
HTTP 클라이언트 테스트를 위한 WireMock - Test MockServer (0) | 2021.10.08 |