ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] OAuth2 (1/2) : 개념 이해
    서버개발/spring-boot 2020. 1. 21. 11:15

    OAuth 란?

     OAuth(Open Authorization, Open Authentication)는 사용자 리소스를 관리하는 서비스(구글, 페이스북 등)에서 제3의 애플리케이션에게 사용자의 패스워드 제공 없이 인증, 인가할 수 있는 인증 관련 표준 프로토콜이다. OAuth 이전에 사용자의 권한을 위임받는 방식은 사용자가 이용하는 서비스의 계정/패스워드를 제공받는 방식이었다. 이는 패스워드 유출 뿐 아니라 권한을 위임받는 애플리케이션이 필요 이상으로 계정에 대한 모든 권한을 획득하게 되는 등 다양한 문제점이 존재한다. OAuth 인증은 API를 제공하는 서버에서 사용자 인증 및 권한 부여를 진행하고 이에 대한 'Access Token'을 발급하는 방식을 제공하며 이러한 문제들을 해결할 수 있다.

     OAuth2는 OAuth1 프로토콜의 복잡한 인증방식을 단순화 한 것이 가장 큰 특징이다.

     

     


    OAuth2 기본 지식

    용어 정리

    Role

     OAuth2 워크플로우상의 역할은 4가지로 구분된다

    • Resource-Owner : 리소스 소유권을 가진 사람
    • Resource-Server : 리소스가 위치한 서버 (ex. google)
    • Client : 리소스를 요청하는 애플리케이션
    • Authorization-Server : 클라이언트 인증, 토큰 발행 등의 역할을 담당하는 서버

     

    Token

     Authorization-Server에 의해 생성되고, 클라이언트의 요청 시점에 발행되는 랜덤 문자열을 의미하며 2가지 타입이 있다.

    1. Access-Token
      : 리소스에 대한 접근을 허용하는 토큰이며, 헤더나 파라미터 등에 담겨 리소스 서버로의 요청에 포함되어야 한다. 만료일이 있으며, Authorization-Server에 의해 정의된다
    2. Refresh-Token(optional)
      : Access-Token 이 만료되기 전에 Authorization-Server에 전송해 토근 기간을 연장하는 데 사용된다.
      OAuth2 Type 중에는 Refresh-Token을 허용하지 않는 경우도 있다.

     

    Access token scope(optional)

     Access-Token의 접근 범위를 지정한다. 스코프 리스트를 Authorization-Server에서 정의하면, Client에서 리소스 요청 시 이 파라미터를 추가해서 보내야 한다. 

     

    권고 사항

    HTTPS 사용

     OAuth2는 Token, 사용자 자격증명 등 민감 데이터가 요청에 담기게 되기 때문에 HTTPS를 사용하기를 권고한다.

     

    클라이언트 등록 절차 필요

     OAuth2를 사용해 리소스를 요청하려면 Authentication-Server에 클라이언트로 등록이 되어야 한다. 이 절차에 대한 승인방법은 OAuth2 제공자(provider)가 정의한다. 클라이언트 등록 절차에 사용되는 가장 기본적인 파라미터는 다음과 같이 정의한다.

    *아래 내용은 실제 구현 시 조금씩 차이가 있을 수 있습니다.

     

    클라이언트 등록 요청

    • Application Name : 클라이언트 애플리케이션 이름
    • Redirect URLs : 인증 코드와 Access-Token을 받을 URL
    • Grant Types : 클라이언트에서 사용하는 인증 방식
    • Javascript Origin(optional) : XMLHttpRequest를 통해 리소스를 요청할 수 있는 hostnames(javascript level에서 http 호출에 사용되는 객체)

    인증서버 응답

    • Client Id : 클라이언트 아이디
    • Client Secret : 클라이언트 시크릿 

     

     


    OAuth2 인증 방식 4 Type

     토큰을 획득하는 데 있어 클라이언트의 위치, 특성에 따라 4개의 승인 타입을 제공한다.

     

    1. 권한 코드 (Authorization grant types)

     

    출처 : http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

    사용

     클라이언트가 웹서버인 경우 주로 사용된다. Refresh-Token(을 Authorization-Server에서 구현한 경우)에 의해 갱신되기 전까지 사용 가능한 기간이 긴(longlived) Access-Token을 허용한다.

     

    예시

    • Resource-Owner : Alice
    • Resource-Server : 구글
    • Client : 웹 사이트
    • Authorization-Server : 구글 인증서버

    시나리오

    1. 웹사이트가 Alice의 구글 프로필 정보를 획득하려 한다.
    2. 웹사이트에서 Alice를 구글 인증 페이지로 redirecting 시킨다.
    3. Alice가 승인하면, 구글 서버에서 웹사이트로 인증 코드를 보낸다.
    4. 클라이언트는 이 코드를 구글 인증서버에 보내 Access-Token을 받는다.
    5. 이후 웹 사이트는 Access-Token을 통해 Alice의 구글 프로필 을 가져온다.

    특징

    • Alice는 Access-Token 을 볼 수 없다. 이 값은 웹사이트(Client)에 저장된다. -> ex. 세션
    • 구글 인증서버는 Access-Token과 더불어 Refresh-Token 도 제공할 수 있다.
    • 토큰은 웹사이트의 브라우 저단으로 넘기지 않는 것이 안전하다.

     

     

    2. 암묵적 허가 (Implicit grant)

     

    출처 : http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

    사용

     클라이언트가 웹 브라우저에서 실행되는 경우 사용된다. 이 타입은 Refresh-Token을 허용하지 않는다.

    예시

    • Resource-Owner : AliceResource-Server : 페이스북
    • Client : 웹 사이트 (AngularJS로 개발된)
    • Authorization-Server : 페이스북 인증 서버

    시나리오

    1. 웹사이트가 Alice의 페이스북 프로필 정보를 획득하려 한다
    2. 웹사이트에서 Alice를 페이스북 인증 페이지로 redirecting 시킨다.
    3. Alice가 승인하면, 페이스북 인증서버가 Alice를 웹 사이트로 redirecting 시키는데, 이때 URL에 Access-Token을 담아 보낸다.
    4. 이후 웹 사이트는 Access-Token 을 통해 Alice의 페이스북 프로필을 가져온다.

    특징

    • Token 은 웹서버로 보내지는 것이 아니기에 URL로 노출된다.
    • CORS(Cross Origin Resource Sharing) 이슈가 발생하지 않는 이유는 페이스북에서 헤더에 Access-Control-Allow-Origin을 담아 보내기 때문이다.
    • refresh-Token을 허용하지 않는다. 

     

     

    3. 자원 소유자의 비밀번호 기반 허가 (Resource Owner Password Credentials Grant)

     Resource-Owner의 ID/PW를 OAuth Access-Token으로 교환할 수 있게 한다.

    출처 : http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

    사용

     클라이언트가 인증서버와 동일한 권한을 가지도록 개발된 경우 주로 사용된다. 예를 들어, 특정 웹사이트 (example.com)에서 API 서버를 오픈하는 경우(api.example.com) 클라이언트와 인증서버는 동일한 권한을 가지고 있다고 볼 수 있다.

    예시

    • Resource-Owner : Alice (academy.com에 계정을 가지고 있는 사용자)
    • Resource-Server : api.academy.com (오픈한 APIs)
    • Client : academy.com
    • Authorization-Server : academy 인증 서버

     

    시나리오

    1. 아카데미에서 관계사에 제공할 API 서버를 오픈했다. 이 API는 Access-Token을 사용한다.
    2. api.academy.com에 접근하면 academy.com의 로그인 페이지로 redirecting 한다.
    3. Alice가 로그인하면 아카데미 서버는 로그인 정보와 Access-Token을 교환한다.
    4. 이후 api.academy.com에서는 이 토큰을 통해 리소스를 요청해 사용한다.

    특징

    • 사용자의 패스워드가 클라이언트로 전송된 후, 인증서버로 다시 전송된다.

     

    4. 클라이언트 인증서(Client Credentials Grant)

     클라이언트가 자원을 소유하고 있거나 권한이 권한 서버에서 미리 준비되어 있을 때 주로 사용된다. 이 방식은 특정 사용자의 권한을 대행하는 방식보다는 저장 서비스나 데이터베이스를 대신하여 API를 사용하려는 애플리케이션에 적합하다.

    출처 : http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

    사용

    클라이언트가 Resource-Owner 인 경우에 사용한다. 따라서 엔드유저로부터의 인증이 생략된다.

    예시

    • Resource-Owner : 웹 사이트
    • Resource-Server : 구글 클라우드 스토리지
    • Client : 웹 사이트(Resource-Owner와 동일)
    • Authorization-Server : 구글 인증서버

    시나리오

    1. 웹 사이트가 파일을 구글 스토리지에 저장하는 방식으로 개발되어 있다.
    2. 웹 사이트는 구글 인증서버를 통해 인증하고 토큰을 발급받는다.
    3. 발급받은 토큰을 이용해서 웹 사이트가 구글 API를 통해 파일을 읽고 쓸 수 있게 된다.

    특징

    • redirect 시킬 URL 이 필요 없다.
    • Refresh-Token은 권장되지 않는다. 의미가 없기에 구현할 필요가 없다.
      (ex. 키 클락의 경우 refresh-token을 사용하려 하면 에러 발생)

     

     


    잘못된 구현으로 인한 인증코드 부여 방식의 취약성

     OAuth2 프로토콜을 제대로 구현하지 않는 경우 마주하게 될 문제들을 몇 가지 살펴보자.

     

    1. 권한 코드 방식의 취약성

    시나리오

    1. 피해자가 취약한 웹 사이트 A에 계정을 가지고 있는 상황으로 가정한다.
    2. A에서는 사용자가 가입할 때 페이스북 계정으로 가입할 수 있는 기능이 있다.(즉, A는 페이스북 인증서버의 클라이언트로 등록되어 있다.
    3. 공격자는 A에서 제공하는 페이스북 연결 기능을 클릭하지만, 별도의 장치를 통해 리다이렉션을 막는다.
      (ex. 파이어폭스의 NoRedirect 플러그인 등)
    4. 공격자는 클라이언트 인증코드를 담고 있는 리다이렉션 URL을 획득한다.
    5. 이후 공격자는 (어떤 수단을 써서라도) 피해자가 해당 URL 을 통해 로그인을 하도록 한다.
    6. 피해자가 탈취된 URL로 로그인을 하게 되면, 이후 공격자의 페이스북 계정과 피해자의 A사이트 계정이 연동되게 되며, 이후 공격자는 자신의 페이스북 계정을 통해 A의 피해자 계정을 제어할 수 있게 된다.

    예방

     state 매개변수를 추가하는 것으로 해결할 수 있다. 일반적으로 사용자의 세션의 임의의 수를 해싱한 값이 함께 들어가도록 한다. 이러한 장치를 통해 만약 로그인 시도 환경이 달라지게 되는 것을 인증서버에서 확인할 수 있게 된다. 

     

    2. 암묵적 허가 방식의 취약성

    시나리오

    1. 공격자가 취약한 A 사이트의 사용자 정보를 해킹하려는 상황이다.
    2. A에서는 페이스북 로그인 기능이 존재한다.
    3. 공격자는 B를 만들어 똑같이 페이스북 로그인 기능을 추가한다.
    4. 피해자는 B에서 페이스북 로그인을 시도하고 이로 인해 Access-Token이 발급된다.
    5. 공격자는 이 토큰을 A사이트에서 이용한다.

    예방

    토큰 정보에 ClientID를 포함하고 이를 체크하는 장치를 추가한다.

     

    3. Clickjacking

    출처 : http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

    시나리오

    1. 공격자가 투명한 Iframe을 이용해서 인증 페이지를 숨긴다. 따라서 해당 페이지에는 눈에 보이지 않는 인증 허가 버튼이 숨겨지게 된다.
    2. 공격자는 피해자가 눈에 보이지 않는(하지만 버튼이 존재하는) 위치를 피해자가 클릭하도록 유도한다.

    예방

    인증서버는 인증 페이지에 X-Frame-Options : DENY, SAMEORIGIN 등을 설정해서 이를 예방한다.

     

     


    참고자료

     

    Understanding OAuth2 « BubbleCode by Johann Reinke

    Understanding OAuth2 Friday January 22nd, 2016 If OAuth2 is still a vague concept for you or you simply want to be sure you understand its behaviours, this article should interest you. What is OAuth2? OAuth2 is, you guessed it, the version 2 of the OAuth p

    www.bubblecode.net

     

    RFC 6749 - The OAuth 2.0 Authorization Framework

    [Docs] [txt|pdf] [draft-ietf-oaut...] [Tracker] [Diff1] [Diff2] [IPR] [Errata] Updated by: 8252 PROPOSED STANDARD Errata Exist Internet Engineering Task Force (IETF) D. Hardt, Ed. Request for Comments: 6749 Microsoft Obsoletes: 5849 October 2012 Category:

    tools.ietf.org

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.