OAuth
제3의 서비스에 계정 관리를 맡기는 방식
용어 정리
리소스 오너(resource owner) : 자신의 정보를 사용하도록 인증 서버에 허가하는 주체. 서비스를 이용하는 사용자가 리소스 오너에 해당된다.
리소스 서버(resource server) : 리소스 오너의 정보를 가지며, 리소스 오너의 정보를 보호하는 주체를 의미. 네이버, 구글, 페이스북이 리소스 서버에 해당한다.
인증 서버(authorization server) : 클라이언트에게 리소스 오너의 정보에 접근할 수 있는 토큰을 발급하는 역할을 하는 애플리케이션.
클라이언트 애플리케이션(client application) : 인증 서버에게 인증을 받고 리소스 오너의 리소스를 사용하는 주체를 의미. 지금 만들고 있는 서비스가 이해 해당한다.
- client_id
- 인증 서버가 클라이언트에 할당한 고유 키. 클라이언트 애플리케이션을 OAuth 서비스에 등록할 때 서비스에서 생성하는 값이다.
- client_secret
- OAuth 서비스에 등록할 때 제공받는 비밀 키.
- grant_type
- 권한 유형을 확인하는 데 사용.
- ex) authorization_code, password, client_credentials, refresh_token
- redirect_uri
- 로그인 성공 시 이동해야 하는 URI
- response_type
- 클라이언트가 제공받길 원하는 응답 타입.
- 인증 코드를 받을 때는 code값을 포함해야 한다. code, token, id_token이 있으며 token, id_token은 implicit 권한부여유형에서 지원해야 한다.
- 서버가 쿼리 문자열에 인증 코드(code), 토큰(token_id, token) 등을 반환
- scope
- 제공받고자 하는 리소스 오너의 정보 목록
- 애플리케이션이 사용자 데이터에 접근하는 것을 제한하기 위해 사용된다.
- 사용자에 의해 특정 스코프로 제한된 권한 인가권을 발행함으로서 데이터 접근을 제한한다.
- state
- 응용 프로그램은 임의의 문자열을 생성하고 요청에 포함하고 사용자가 앱을 승인한 후 서버로부터 동일한 값이 반환되는지 확인해야 한다.
- 이것은 CSRF 공격을 방지하는 데 사용된다.
리소스 오너 정보를 취득하는 4가지 방법
- 권한 부여 코드 승인 타입(authorization code grant type) → 가장 많이 사용하는 방식
- 암시적 승인 타입(implicit grant type)
- 리소스 소유자 암호 자격증명 승인 타입(resource owner password credentials)
- 클라이언트 자격증명 승인 타입(client credentials grant)
4가지 방법 중에서 가장 많이 사용하는 권한 부여 코드 승인 타입에 대해서 알아보겠다.
권한 부여 코드 승인 타입
OAuth 2.0에서 가장 잘 알려진 인증 방법으로서, 클라이언트가 리소스에 접근하는 데 사용하며 권한에 접근할 수 있는 코드와 리소스 오너에 대한 액세스 토컨을 발급 받는 방식이다. 이 방법은 서비스에서 가장 중요한 정보인 사용자 데이터가 외부로 전송되지 않아 안전하고, OAuth에서 가장 잘 알려진 방법이다.
- 권한 부여 승인 코드 요청
- 권한 요청은 클라이언트, 즉, 스프링 부트 서버가 특정 사용자 데이터에 접근하기 위해 권한 서버(카카오나 구글 권한 서버)에 요청을 보내는 것이다. 요청 URI는 권한 서버마다 다르지만 보통은 client_id, redirect_uri, response_type 등을 파라미터로 보낸다.
GET spring-authorization-server.example/authorize?
client_id=66a36b4c2&
redirect_uri=http://localhost:8080/myapp
response_type=code&
scope=profile
- 데이터 접근용 권한 부여 - 클라이언트(애플리케이션)은 권한 서버에서 제공하는 로그인 페이지를 브라우저에 띄우 출력해준다.
- 권한 부여 승인 코드 전달 - 사용자가 로그인을 하면 권한 서버(인증 서버)는 권한 부여 인증 코드 요청 시 전달받은 redirect_uri로 Authorization code를 전달한다.
- Access Token 요청 - 인증 코드를 받으면 액세스 토큰으로 교환해야 한다. 액세스 토큰은 로그인 세션에 대한 보안 자격을 증명하는 식별 코드를 의미. 보통 다음과 같이 /token POST 요청을 보낸다.
POST spring-authorization-server.example.com/token
{
"client_id": "66a36b4c2",
"client_secret": "aabb11dd44",
"redirect_uri": "http://localhost:8080/myapp",
"grant_type": "authorization_code",
"code": "a1b2c3d4e5"
}
- Access Token 전달 및 보호된 자원 요칭 및 전달(액세스 토큰으로 API 응답 & 반환)
- 제공받은 액세스 토큰으로 리소스 오너의 정보를 가져올 수 있다. 정보가 필요할 때 마다 API 호출을 통해 정보를 가져오고 리소스 서버는 토큰이 유효한지 검사한 뒤에 응답한다.
ex) 리소스 오너의 정보를 가져오기 위한 요청 예
GET spring-authorization-resource-server.example.com/userinfo
Header: Authorization: Bearer aasdffb