본문 바로가기

old/Cyber Security

OAuth 2.0까지의 인증 방식의 진화

반응형

HTTP와 로그인 인증 기술의 필요성

인터넷이 생겨나던 당시에 생겨난 HTTP프로토콜은 당시에 빠르게 정보를 주고 받기 위한 일종의 구칙이였습니다. 서버에서는 클라이언트의 정보를 보관하지 않고, 그저 요청이 들어오는데로 데이터를 준비해서 응답을 하는 단순한 일만 하는것이 서버였습니다. 이렇게 클라이언트의 정보를 저장하지 않는 특성을 stateless라고 부릅니다.

하지만 시간이 지나고 기술이 발전함에 따라서 서버에서는 클라이언트가 누군지 구분해야 할 필요성이 생겨났습니다. 클라이언트가 쇼핑몰에서 장바구니에 넣은 물건들이 뭔지 클라이언트마다 다르게 표기해야 했기 때문입니다. 이를 위해서 여러가지 로그인 인증 기술이 탄생하게 되었습니다.

Cookie

가장 최초로 나온 로그인 인증기술인 쿠키는 아이디와 비밀번호를 서버에 저장해두고, 클라이언트가 아이디와 비밀번호를 서버에 보내면 서버에서 확인하는 방식이였습니다.

쿠키는 일반적으로 Request할떄 사용하는 방식인 HTTP URI 안에서 Header부분에 저장되는데, Header는 정보요청시 매우 쉽게 확인할수 있었기 떄문에 request중간에 이 정보를 탈취하여 아이디와 비밀번호가 남에게 알려지는 경우가 많았습니다.

Session

Session이라는 저장소를 생성해서 클라이언트의 아이디와 비번을 저장하고 고유의 Session ID를 생성하여 Session에 저장하기 시작했습니다. 그 후에 클라이언트가 로그인을 할때, 아이디와 비밀번호가 아닌 Session ID를 서버에 보냈고, 서버에서는 이를 이용해서 클라이언트를 구분했습니다.

아이디와 비밀번호는 최초 한번만 전송되었기 때문에 탈취당하기는 어려웠고, Session ID는 아이디와 비밀번호와는 전혀 관계가 없었기 때문에 보안성이 쿠키만 사용할떄보다는 좋아졌습니다. 하지만 여전히 Session ID를 이용해서 로그인은 가능했기떄문에 보안성이 그리 높진 않았습니다.

이후, 이를 보안하기 위해서 세션ID의 만료시간을 주어 시간이 지나면 사용할수 없도록 하였지만, 이는 클라이언트에게 있어서 번거로웠고, 효과도 좀 부족했습니다.

Access Token

그 다음 Access Token이라는 것이 만들어졌습니다. 기본적으로 Session ID와 비슷하지만, Session ID가 단순하게 부여된 숫자였던것에 반해서 Access Token은 인증에 필요한 정보를 모아서 암호화 한 정보입니다. 이 정보들 보통 JWT (JSON Web Token)방식으로 저장합니다.

JWT (JSON Web Token) 구성 요소

[Header].[Payload].[Signature]
  • Header: Access Token의 타입과 암호화 방법이 들어갑니다.
{ 
"typ": "JWT", 
"alg": "SHA256" 
}
  • Payload: 인증에 필요한 정보가 들어갑니다. 토큰 생성시간, 토큰 활성 날짜, 토큰 만료날짜 등등이 들어갑니다. 클라이언트와 관련된 정보(아이디, 비밀번호 등)은 들어가지 않습니다.
{ 
"sub": "1", 
"iss": "ori", 
"exp": 1636989718, 
"iat": 1636987918 
}
  • Signature: payload의 정보와 서버의 개인키를 사용해서 header에 명시된 SHA256알고리즘을 사용하여 만든 문자열 입니다. 이를 이용해서 토큰을 인증하므로, 만약 토큰이 변조되었다면 바로 알수 있습니다.
{ 
"SHA": "9F69FA131C4CA518D3CCE296013D9A3C2B4AA63CA02583C8B6F1F7F354A1D874" 
}

Access Token and Refresh Token

Access Token은 다른문제가 있는데, 암호화에 유효기간을 사용하기 떄문에 기존의 Access Token이 만료 전에는 새로운 토큰을 만들수 없다는 것이다. 그렇다고 유효기간을 짧게 만든다면 클라이언트에게 불편함이 생긴다. 그래서 생겨난 것이 Refresh Token이다.

 

Access Token은 유효기간이 짧게, Refresh Token은 유효기간이 길게 만들어서 클라이언트에게 발급하고, 나중에 Access Token이 만료되었을떄, Refresh Token을 받아서 인증하고 새로운 Access Token을 발급해주는 것이다.

Refresh Token은 Access Token이 만료되었을 떄만 서버로 보내기 때문에 탈취되기 어렵고, Access Token은 자주 재발급이 되니 탈취하기가 어려워진다.

OAuth(Open Authorization) 1.0

OAuth 1.0은 아이디와 비밀번호를 보호하기 위해서 또다른 애플리케이션을 추가하였습니다. 이 어플리케이션은 일종의 사용자 인증을 위한 독립적인 서비스로 사용되었습니다. 이 서비스를 consumer라 불렀습니다.

User: 사용자

Service provider: 구글 OAuth Service

Consumer: 트위터

  1. 사용자가 트위터 로그인을 시도
  2. 트위터가 구글 OAuth Service에게 Request Token을 요청합니다
  3. 구글 OAuth Service는 트위터가 보낸 Key, Secret을 확인하고 Request Token을 생성해줍니다.
  4. 트위터는 로그인 페이지를 구글OAuth Service를 통해 보여줍니다.(redirect)
  5. 사용자가 로그인하는 정보(아이이, 비밀번호)는 구글OAuth Service에게 전달됩니다.
  6. 구글 OAuth Service은 발행했던 Request Token과 아이디와 비밀번호를 확인합니다.(로그인 인증)
  7. 인증이 잘 되었다고 트위터에게 알립니다.
  8. 트위터는 사용자가 로그인 인증을 받았으므로, Access Token을 구글 OAuth Service에게 요청합니다.
  9. 구글 OAuth Service는 Access Token을 생성해서 트위터에게 보냅니다.
  10. 트위터는 사용자에게 Access Token을 줍니다. 연결 완료.
  11. 이후 Access Token이 만료되기 전까진 이를 이용해서 사용자가 로그인합니다.

결론적으로, 유저(User), 유저가 사용하려는 사이트(Consumer), 유저 정보를 가진 또 다른 웹서비스(Service Provider)가 서로 상호작용하여 작동하는 방법인데, 이는 구현이 복잡하고, Refresh Token이 없어짐으로서 기존의 Access Token이 만료전에는 새로운 토큰을 만들수 없다는 문제가 있었습니다. 또한 반드시 웹페이지를 통해서만 인증이 가능했습니다.

OAuth(Open Authorization) 2.0

1.0 단점 2.0에서 개선점

통신상에서 보안이 안됨 HTTP가 아닌 HTTPS를 사용
너무 복잡함 기능의 단순화
Access Token이 만료전엔 재발급 불가 Refresh Token 도입
로그인 인증은 반드시 웹싸이트를 통해서만 가능 로그인 인증방식을 늘림

또한 로그인 인증을 하기 위한 서버와 사용자의 요청을 처리하는 서버를 분리해서 관리함으로서, Access Token이나 사용자의 ID, PWD가 탈취되기 어렵게 만들었습니다.

Resource Server (자원 서버) 액세스 토큰을 가진 요청에 응답하며 자원을 관리하는 서버

Authorization Server (인증 서버) 클라이언트가 리소스 서버의 서비스를 이용할 수 있도록 인증하고 토큰을 발급하는 서버
Resource Owner (사용자) 리소스 서버의 계정을 소유한 사용자
Client (웹 브라우저) 리소스 서버의 API를 사용하여 데이터를 가져오려는 웹 사이트
Access Token 리소스 서버에 자원 요청을 할 수 있는 토큰
Refresh Token 인증 서버에서 액세스 토큰을 재발급받을 수 있는 토큰

Authorization Code Grant

  • 사용 권장
  • 보안성이 높음: AccessToken을 바로 클라이언트로 전달하지 않아 잠재적 유출을 방지
  • 일반적으로 백엔드 서버에서 많이 사용

  1. 사용자가 클라이언트를 이용하여 자신의 아이디와 비밀번호를 인증 서버에 전송합니다. 인증 서버에서 로그인이 성공적으로 이루어지면, 사용자에게 인증 코드를 발급합니다.
  2. 클라이언트는 인증 코드를 인증 서버에 전송하고 액세스 토큰을 요청합니다. 인증 서버는 인증 코드를 확인한 후 액세스 토큰과 리프레시 토큰을 발급합니다.
  3. 클라이언트는 발급받은 액세스 토큰을 사용하여 리소스 서버의 리소스에 접근할 수 있게 됩니다.
  4. 액세스 토큰이 만료되면, 클라이언트는 리프레시 토큰을 사용하여 인증 서버에 접근하고 새로운 액세스 토큰을 발급받습니다.

Implicit Grant

  • 사용 권장
  • 인증방식중에서 가장 많이 사용됨
  • 일반적으로 사용자가 쇼핑몰에 로그인할때 사용(User Agent Application)

  1. 사용자가 클라이언트를 사용하여 인증 서버에 로그인을 시도합니다. 인증 서버에서 로그인 인증이 완료되면, 액세스 토큰을 발급합니다.
  2. 인증 서버는 클라이언트에게 발급된 액세스 토큰을 포함한 리디렉션 응답을 반환합니다. 이 때, 액세스 토큰은 URI 프래그먼트에 포함되어 있습니다.
  3. 클라이언트는 리디렉션 응답에서 액세스 토큰을 추출한 후, 이를 사용하여 리소스 서버의 리소스에 접근을 시도합니다. 리소스 서버는 액세스 토큰의 유효성을 인증 서버와 확인한 후, 유효한 경우 클라이언트가 요청한 리소스에 접근할 수 있게 됩니다.

Resource Owner Password Credentials Grant

  • 사용 비권장
  • 모든 유형의 어플리케이션에서 사용 가능
  • 일반적으로 API을 사용한 연결시 사용

  1. 사용자는 클라이언트를 사용하여 아이디와 비밀번호, 그리고 클라이언트 정보를 인증 서버에 전송합니다. 인증 서버에서 로그인 인증과 클라이언트 정보가 인증되면 액세스 토큰을 발급합니다.
  2. 클라이언트는 발급받은 액세스 토큰을 사용하여 리소스 서버의 리소스에 접근할 수 있게 됩니다.

Client Credentials Grant

  • 비권장
  • 클라이언트 인증만으로 바로 엑세스 토큰 발급 가능
  • 사용자 관련 데이터가 아닌 애플리케이션 간 데이터에 접근하는 데 사용

  1. 클라이언트는 클라이언트 정보(클라이언트 ID와 클라이언트 비밀)를 인증 서버에 전송합니다. 인증 서버에서 클라이언트 정보가 인증되면 액세스 토큰을 발급합니다.
  2. 클라이언트는 발급받은 액세스 토큰을 사용하여 리소스 서버의 리소스에 접근할 수 있게 됩니다.

Device Code Grant

  • 비권장
  • 별도의 기기를 사용해서 인증을 진행
  • 웹 브라우저가 없거나 입력이 제한된 장치(예: 스마트 TV, 게임 콘솔)에서 사용

  1. 입력이 제한된 장치에서 사용자가 클라이언트 애플리케이션을 시작합니다. 클라이언트는 장치 코드, 사용자 코드, 그리고 검증 URL을 인증 서버에 요청합니다.
  2. 인증 서버는 장치 코드, 사용자 코드, 그리고 검증 URL을 클라이언트에 반환합니다. 사용자는 다른 기기(예: 스마트폰, 컴퓨터)에서 검증 URL에 접속하여 사용자 코드를 입력하고 로그인합니다.
  3. 클라이언트는 인증 서버에 device 코드와 클라이언트 식별자를 전송하며 액세스 토큰 발급을 요청합니다.
  4. 사용자가 검증 URL에서 로그인 인증을 완료하면 인증 서버는 액세스 토큰을 발급하고, 클라이언트는 액세스 토큰을 사용하여 리소스 서버의 리소스에 접근할 수 있게 됩니다.

Refresh Token Grant

Access Token을 Refresh Token을 사용해서 재발급한다. 원래 있던 Access Token은 기간이 만료된다.

 

반응형