OAuth 2.0
OAuth 2.0은 자신이 소유한 리소스에 소프트웨어 애플리케이션이 접근할 수 있도록 허용해줌으로써 접근 권한을 위임해주는 프로토콜이다.
토큰을 이용해 애플리케이션이 해당 리소스에 접근할 수 있습니다.
-
리소스 소유자
일반적으로 리소스 소유자는 서비스 사용자, 웹 브라우저를 이용한다고 가정
-
보호된 리소스 리소스 소유자가 접근하는 구성 요소이다.
대부분 웹 API의 형태를 띤다. API를 통해 읽고 쓰는 작업
-
클라이언트
리소스 소유자 대신 보호된 리소스에 접근하는 소프트웨어 요소
인가 그랜트 절차
이전에도 OAuth 2.0 인가 그랜트 절차에 대해 학습한 적이 있는데
페이코 개발자 센터 이미지를 참고하여 다시 기억해보자.
참고: https://developers.payco.com/guide/development/start
과거의 자격 증명 공유 (와 자격 증명 탈취)
기업 환경에서 많이 사용되는 한 가지 방법은 사용자의 자격 증명을 복사해 연결하고자 하는 다른 서비스에 전달하는 것이다.
이 경우 클라이언트가 마치 사용자인 것처럼 사용자가 입력한 id/password를 보호된 리소스에 전달한다.
위 방법이 가능하기 위해서는 클라이언트 애플리케이션과 보호된 리소스에 대한
사용자의 자격 증명이 동일해야 하며 다음과 같은 문제점이 생긴다.
- 자격 증명 탈취에 대한 보안성이 제한
ex) 하나의 기업이 동일한 정책과 네트워크 통제 안에서 클라이언트와 인가 서버, 보호된 리소스를 운영하면
사용자는 그 기업의 여러 서비스에 대해 동일한 자격 증명을 이용할 수 있다.
- 사용자의 비밀번호가 클라이언트 애플리케이션에 노출
- 보호된 리소스 입장에서 자신에게 접근하는 것이 실제 리소스 소유자인지 클라이언트인지 구분할 수 없다.
OAuth 2.0 장단점
장점
-
사용자의 권한 위임 결정은 캡처하고 네트워크상에 표현하는 데 매우 뛰어나다.
-
보안 결정 절차에 여러 당사자가 참여할 수 있으며, 특히 런타임 시 사용자가 보안 결정을 한다.
-
유사한 프로토콜에 비해 훨씬 간단하고 안전하다.
-
클라이언트 개발자가 이전의 보안 프로토콜처럼 더 이상 시그니처 정규화나 복잡한 보안 정책 문서를 분석하지 않아도 된다.
-
OAuth 토큰을 제대로 사용하면 보다 향상된 보안성을 제공한다.
-
만약 어떤 클라이언트가 침해된다면, 피해는 해당 클라이언트의 사용자로 국한된다.
클라이언트가 침해되더라도 리소스 소유자의 자격 증명 데이터는 유출되지 않는다. -
독립적인 개발자가 수천 개의 클라이언트를 안전하게 관리하는 것보다 하나의 인가 서버를 안전하게 관리하는 편이 훨씬 쉽다.
-
OAuth 2.0의 확장성과 모듈화 > 다양한 환경에서도 적용해 사용할 수 있다.
단점
-
유연성으로 OAuth 구현체 간의 기본적인 호환성에 문제가 발생할 수 있다.
-
OAuth의 스펙에는 많은 부분을 선택 사항으로 기술하고 있기 때문에
두 시스템 간에 OAuth를 구현하고자 하는 개발자들을 혼란스럽게 만들 수 있다. -
선택 사항 중 일부를 잘못 이해하거나 적절히 수행하지 않으면 안전하지 않은 OAuth 구현이 될 수 있다.
OAuth 2.0이 아닌 것
OAuth가 널리 쓰임에도 실제로 보면 OAuth가 아닌 것이 많다.
프로토콜을 이해함에 있어서 차이점이 무엇인지 이해하는 것도 중요하다.
-
OAuth는 HTTP 프로토콜과 독집적으로 정의되지 않는다.
OAuth 2.0 토큰은 메시지 시그니처를 제공하지 않기 때문에 HTTPS를 이용해야 한다. -
OAuth는 인증 프로토콜이 아니다.
OAuth 트랜잭션 자체만으로 사용자가 누구인지 알 수 없다.
또한, OAuth는 여러 곳에서 인증을 사용한다.
그렇다고 해서 내제된 인증 자체만으로 OAuth가 인증 프로토콜이 되지는 않는다. -
사용자 간의 권한 위임 메커니즘은 정의하지 않는다.
리소스 소유자가 다른 사람을 인가할 수 있게 하려면 OAuth만으로는 힘들다. -
OAuth는 인가 절차 메커니즘을 정의하지 않는다.
권한 위임이 이뤄졌다는 사실을 전달하는 방법을 제공하지만, 권한 인가 자체의 내용을 정의하는 것은 아니다. -
OAuth는 토큰의 포맷을 정의하지 않는다.
OAuth 프로토콜은 토큰의 내용이 클라이언트 애플리케이션에게 완전히 불투명하다고 명확히 기술하고 있다. -
OAuth 2.0은 1.0과 달리 암호화 방법을 정의하지 않는다.
-
OAuth 2.0은 단일 프로토콜이 아니다.
OAuth 스펙은 사용 방법이 각기 다른 여러 가지 정의와 흐름으로 나뉜다.
참고 33p - 56p
클라이언트에 대한 CSRF 공격
인가 코드 그랜트 타입과 암시적 그랜트 타입에서 상태(state) 파라미터 사용을 권장하고 있다.
클라이언트가 요청과 콜백 사이의 상태를 유지하기 위해 사용하는 구조가 정해지지 않은 값으로서
인가 서버는 유저에이전트를 클라이언트로 다시 리다이렉트 시킬 때 이 값을 전달한다.
CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해 이 값을 사용해야 한다.
CSRF란 악의적인 애플리케이션이 현재 사용자가 인증된 웹 사이트로
사용자의 웹 브라우저가 요청을 보내게 함으로써 원하지 않는 작업이 이뤄지도록 만드는 것이다.
웹 브라우저가 요청을 만들고(쿠키를 이용해) 그로 인해 특정 작업이 수행된다는 것이다.
CSRF 공격을 막기 위한 가장 일반적이고 효과적인 방법은 각각의 HTTP 요청에 예측할 수 없는 값을 추가하는 것이다.
이는 OAuth 스펙에서도 설명하는 방법이다.
참고 195p
OAuth 토큰이 무엇인가?
클라이언트는 인가 서버로부터 토큰을 발급받아 보호된 리소스에 전달한다.
인가 서버는 토큰을 생성해 클라이언트에게 발급하고,
토큰을 리소스 소유자의 권한 위임과 클라이언트의 권한과 연결시켜 관리한다.
보호된 리소스는 클라이언트로부터 전달받은 토큰이 클라이언트가 요청한 작업을 수행할 수 있는 권한이 있는지 확인한다.
토큰은 권한 위임 행위 결과를 나타낸다.
이렇게 중요한데 OAuth에서 토큰에 대한 언급이 전혀 없다.
왜 구체적으로 정의하지 않을까?
토큰을 구체적으로 정의하지 않는 이유는 OAuth 특성이나 위험 환경 그리고 요구 사항이 각기 다른 다양한 곳에서 적용해 사용할 수 있기 때문이다.
토큰의 유효 기간이 만료되거나 폐기될 수 있고, 무기한으로 지정해 사용하거나 다양한 조랍으로 사용할 수 있다.
또한 시스템의 특정 사용자나 모든 사용자를 나타내거나 아무런 사용자도 나타내지 않을 수 있다.
참고 278p
구조화된 토큰: JSON Web Token
공유해 사용하는 데이터베이스에서 토큰을 찾는 것 대신 토큰 안에 필요한 정보를 담아 만들면 어떨까?
그렇게 하면 인가 서버는 어떤 네트워크 API 호출 없이 도큰 자체 만으로 보호된 리소스와 간접적으로 통신할 수 있게 된다.
인가 서버가 JWT를 지원하도록 수정한다고 가정해보자.
토큰의 구조가 이전과 달라졌는데도 클라이언트 코드는 수정할 필요가 없다.
이는 클라이언트에게 있어서 토큰의 구조는 명확하지 않다는 OAuth 2.0의 중요한 스펙 덕분이라고 할 수 있다.
참고 279p
OAuth 2.0이 인증 프로토콜이 아닌 이유
먼저, 인증이란 무엇인가?
인증은 현재 사용자가 누구인지 그리고 현재 사용자가 애플리케이션을 사용하고 있는지 여부를 애플리케이션에게 알려주는 것이다.
일반적으로 자격 증명(id/password 같은)을 애플리케이션에 제공함으로써
사용자가 현재 주장하는 자신임을 알리는 보안 아키텍처의 일부분이라고 할 수 있다.
하지만 OAuth 2.0은 자체적으로 사용자에게 어떤 것도 알려주지 않을 뿐만 아니라
사용자가 자신의 존재를 어떻게 증명했는지 또는 존재했는지에 대해서도 알려주지 않는다.
토큰을 요청하고 획득, 그 토큰을 이용해 API에 접근하지만
누가 해당 클라이언트를 인가했는지 또는 인가되는 과정에 사용자가 있었는지는 전혀 알지 못한다.
클라이언트에게 권한을 인가하기 위한 강력한 패러다임이지만
사용자가 현재 있고, 누군지를 알아내는 인증과는 상반된다고 할 수 있다.
참고 354p
인증(Authentication) vs. 인가(Authorization)
둘은 표면적으로는 유사하지만 기본적인 성격은 분명히 다르다.
-
인증(Authentication)
클라이언트가 자신이 주장하는 사용자와 같은 사용자인지를 확인하는 과정
ex) 방문자가 자신이 회사 건물에 들어 갈 수있는지 확인 받는 과정이다. -
인가(Authorization)
권한부여, 클라이언트가 하고자 하는 작업이 해당 클라이언트에게 허가된 작업인지를 확인
ex) 방문자가 회사 건물에 방문했을 때, 허가된 공간에만 접근 가능하다.
인증을 거친 후 인증된 사용자에 대한 특정한 권한을 부여 한다.
이 게시글은 OAuth2 In Action 를 참고하여 작성되었습니다.😇