인증 유형(Authorization Grant Types) 시퀀스 다이어그램
1. Authorization Code
리소스 접근을 위한 계정 정보, 권한 서버에 요청하여 받은 권한 코드를 함께 활용하여 리소스에 대한 Access Token을 받는 방식이다.
– 권한 서버가 클라이언트와 리소스 서버 간의 중재역할을 한다.
– Access Token을 바로 클라이언트로 전달하지 않아 유출을 방지한다.
– 로그인 시 페이지 url에 response_type=code 로 넘긴다.
2. Implicit
인가 코드 승인 방법과 다르게 권한 코드 교환 단계 없이 Access Token을 즉시 반환받아 이를 인증에 사용하는 방식이다.
– 권한코드 없이 바로 발급되어 보안에 취약하다.
– 로그인 시 페이지 url에 response_type=token 으로 넘긴다.
3. Resource Owner Password Credentials
클라이언트에 계정정보(ID, Passwd)를 저장하고, 계정정보로 직접 Access Token을 받아오는 방식이다.
– 로그인 시 API에 POST로 grant_type=password 로 넘긴다.
4. Client Credentials
클라이언트가 Confidential Client 일 때, 외부에서 Access Token을 얻어 특정 리소스에 접근을 요청할 때 사용하는 방식이다.
– 로그인 시 API에 POST로 grant_type=client_credentials 로 넘긴다.
Redirect
OAuth2.0의 로그인 페이지 URL은 HTTP Respinse Status Code 302 요청으로 리소스가 임시적으로 새로운 URL로 이동함을 나타낸다. 아래 주소는 해당 페이지에서 추출한 페이지 URL이다.
https://nid.naver.com/oauth2.0/authorize?client_id=DZ724qNQ4ceqJfMyrKiS&response_type=code&redirect_uri=https%3A%2F%2Fwww.idlookmall.com%2FnaverAccess.do&state=85m585fpoabj2erinttpdpsa0e
Access Token
OAuth 인증 플로우에서 핵심 구성요소인 Access Token에 대해 알아보자. Access Token은 인증 서버에서 발급받아, 리소스 서버에게서 리소스 소유자의 보호된 자원을 획득할 때 사용되는 만료기간이 있는 Token이다. 가장 대표적인 Access Token인 JWT에 대해 알아보도록 하자.
JWT 웹 토큰이란
JWT(JSON Web Token)는 당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 자체 포함된 방법을 정의하는 개방형 표준( RFC 7519 )이다. 이 정보는 디지털 서명되어 있으므로 확인하고 신뢰할 수 있다. JWT는 HMAC 알고리즘을 사용하거나 RSA 또는 ECDSA 를 사용하는 공개/개인 키 쌍을 사용하여 서명할 수 있다.
JWT 구조 (Header, Payload, Signature)
JSON은 점(.)으로 구분된 세 부분으로 구성되며 다음과 같다.
Header
Header는 JWT인 토큰 유형과 HMAC SHA256 또는 RSA와 같이 사용중인 서명 알고리즘 두 부분으로 구성된다. Alg는 서명 시 사용하는 알고리즘이고, type 토큰 유형이다.
그 후 이 JSON을 Base64Url로 인코딩하면 JWT의 헤더부분인 첫 부분을 형성한다.
Payload
JWT의 두번째 부분은 Payload이다. 페이로드의 속을을 클래임 셋(Claim Set)이라고 부른다. 클레임은 사용자 추가 데이터에 대한 설명이다.
페이로드는 Base64Url로 인코딩되어 JSON의 두 번째 부분을 형성한다.
Signature
서명 부분을 생성하려명 인코딩된 Header, Payload, secret, Header에 저장된 알고리즘을 가져와 서명해야 한다. 서명은 메시지가 도중에 변경되지 않았는지 확인하는 데 사용되며 개인로 서명된 토큰의 경우 JWT를 보낸 사람이 누구인지 확인할 수 있다.
예를 들어 HMAC SHA256 알고리즘을 사용하는 경우 서명은 다음과 같은 방식으로 생성된다.
다음은 Header와 Payload로 인코딩되어 있고, secret으로 서명된 JWT이다. 이러한 개념을 JWT 디버거를 사용하여 디코딩, 확인 및 생성할 수 있다.
JWT 사용 시나리오
Authorization(권한 부여)
JWT를 사용하는 가장 기본적인 시나리오이다. 사용자가 로그인하면, 서버는 사용자 정보를 기반으로 하여 토큰을 발급한다. 그 후, 후속 요청에는 사용자가 서버에 요청할 때마다 JWT가 포함되어 전달한다. 서버는 클라이언트에서 요청을 받을때 마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 사용자가 요청한 작업에 권한이 있는지 확인하여 작업을 처리한다. 따라서 서버에서는 사용자에 대한 세션을 유지할 필요가 없게 된다.
Information Exchange(정보 교환)
JWT는 당사자간에 정보를 안전하게 전송하는 방법이다. 예를 들어 공개/개인 키 쌍을 사용하여 JWT에 서명할 수 있기 때문에 발신자가 누구인지 확인할 수 있다. 또한 Header와 Payload를 사용하여 서명을 계산하므로 내용이 변조되지 않았는지 확인할 수 있다.
마치며
OAuth에 대한 이해를 시작으로 JWT까지 살펴보았다. JWT와 OAuth는 인증 관점에서 비교할 때, 서로 추구하는 목적이 다르다.
OAuth는 인증 서버의 권한(무작위 문자열 토큰)으로 다양한 플랫폼에서 권한을 행사할 수 있에 함으로써 리소스 접근이 가능하게 하는데 목적이 있다. JWT는 Cookie, Session을 대신하여 의미있는 문자열 토큰으로써 권한을 행사하는 토큰의 한 형식이다. OAuth에서 사용하는 토큰이 의미있는 정보를 가져야한다면, Access Token을 JWT형식으로도 구현할 수 있다.
서버 인증에 대한 단계별 개념 이해를 위해 시리즈로 정리를 해보았다. 이 글이 서버 및 인증에 대한 이해, 상식 성장과 더불어 더 나은 IT 엔지니어가 되기 위한 시작점이 되길 바란다.
출처
https://showerbugs.github.io/2017-11-16/OAuth-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
https://hwannny.tistory.com/92
https://devbksheen.tistory.com/39