OAuth

양치는 하셨나요·2024년 8월 13일

오어쓰? 아어쓰? 단어 자체는 들어봤지만 어떻게 읽는지도 모르는 이 단어 절대 영어 못하는거 맞습니다..

인증과 인가를 조사하며 인증을 도와주는 기능을 한다는 사실만 알고 있어 이전부터 계속 조사하고 있는 보안과 관해서 빠질 수 없는 내용으로 나오기에 이에 대한 조사도 진행하였다.

OAuth

개념

애매한 단어가 나왔을 땐 역시 위키백과에서 한 번 살펴보고 가야한다.

OAuth("Open Authorization")는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다

차근차근 짚어본다면 아래와 같은 내용으로 생각할 수 있다.

  • 로그인 없이 사용자 정보에 대한 접근 권한을 부여 가능한 수단.
  • 이에 관한 개방형 표준

구성 요소

  • Resource Owner 웹 서비스를 이용하려는 유저, 자원(개인정보)을 소유하는 자, 사용자
    'Resource' 는 개인정보라고 생각하면 된다.
  • Client
    자사 또는 개인이 만든 애플리케이션 서버
    클라이언트 라는 이름은 client가 Resource server에게 필요한 자원을 요청하고 응답하는 관계여서 그렇다.
  • Authorization Server
    권한을 부여(인증에 사용할 아이템을 제공주는)해주는 서버다.
    사용자는 이 서버로 ID, PW를 넘겨 Authorization Code를 발급 받을 수 있다.
    Client는 이 서버로 Authorization Code을 넘겨 Token을 받급 받을 수 있다.
  • Resource Server
    사용자의 개인정보를 가지고있는 애플리케이션 (Google, Facebook, Kakao 등) 회사 서버
    Client는 Token을 이 서버로 넘겨 개인정보를 응답 받을 수 있다.

역사

  1. OAuth가 사용되기 전에는 인증방식의 표준이 없었기 때문에 기존의 기본인증인 아이디와 비밀번호를 사용
    • 보안상 취약한 구조일 가능성이 높음
  2. 기본 인증이 아닐 경우는 각 애플리케이션들이 각자의 개발한 회사의 방법대로 사용자를 확인
    • ex) 구글의 AuthSub, AOL의 OpenAuth, 야후의 BBAuth, 아마존의 웹서비스 API 등

→ OAuth는 이렇게 제각각인 인증방식을 표준화한 인증방식

OAuth를 이용하면 이 인증을 공유하는 애플리케이션끼리는 별도의 인증이 필요 없기에 여러 애플리케이션을 통합하여 사용하는 것이 가능

OAuth 1.0

  • 2006년에 트위터의 개발자와 소셜 북마크 서비스인 Gnolia의 개발자가 만나 인증 방식을 논하면서 시작
    • 그전까지 인증 위임에 대한 표준안이 없었다.
    • 2007년 4월 OAuth 논의체를 만들었다.
    • 2010년 IETF(국제 인터넷 표준화 기구)에서 OAuth 1.0 프로토콜 표준안 발표한다.
  • 특징
    • API 인증 시, 써드파티 어플리케이션에게 사용자의 비번을 노출하지 않고 인증
    • 인증과 API 권한부여를 동시에 할 수 있다
  • 문제점
    • 서명 계산이 복잡해 구현이 어렵고 모든 부분에서 서명이 필요했다.
    • 위의 문제로 오류가 발생할 수 있었고 보안에 취약할 수 있다.

OAuth 2.0

  • 이런 문제를 해결하기 위해 2012년 OAuth 2.0이 등장했다.
  • 특징
    • 웹 이외의 애플리케이션 지원 강화
    • HTTP를 통한 토큰 발급으로 클라이언트의 암호화 필요성 감소
    • 서명을 단순화하였다.
    • Access 토큰 갱신으로 계속 사용 가능
      • Refresh 토큰으로 새로운 Access 토큰 발급 가능
    • 요청 처리(인증) 서버와 권한 처리(인가) 서버를 완전히 분리

차이

OAuth 2.1

아직 확정 되진 않았지만 계속 개발중인 프로토콜이다.

  • 이전에 있던 여러 권장 사항들을 통합해 더 간단하고 명확한 표준을 제공한다.
  • 비밀번호 기반의 오래된 방식을 제한한다.
  • HTTPS 사용을 강제하고 보안 강화를 위한 추가 사항을 포함한다.

그래서 어떤 것을 써야 할까?

현재는 2.0을 주력으로 사용하고 있다고 한다. 이유는 아래와 같다.

  • 현재 대부분의 웹 애플리케이션에서 채택한 표준이다.
  • 유연성과 확장성이 좋다.
  • Refresh 토큰으로 토큰 갱신이 가능하다.
  • 복잡성이 낮아 상대적으로 구현이 간편하다.

그렇다고 2.1을 배제할 순 없다. 이전의 블로그들에서 봤듯 최신 기술들은 결국 개발되고 적용될 것이며 현재에도 2.1이 적용되는 곳들이 있다고 하니 상황에 따라 2.0과 2.1을 사용해야 한다.

동작

현재 주력인 OAuth 2.0을 기준으로 설명한다.

2.0은 1.0에서 인증과 인가를 확실히 분리하기 위해 만들어졌었는데 이 중 인가는 권한을 부여하는 과정을 의미한다.

OAuth2.0은 4가지의 권한 부여 방식을 가지고 있어 이 4가지에 대해 설명한다.

  1. Authorization Code Grant (인가 코드 방식)

    • 가장 일반적으로 사용되는 OAuth 2.0 인증 방식
    • 웹 애플리케이션에서 주로 사용되며, 백엔드 서버를 통해 클라이언트가 액세스 토큰을 요청하는 방식
    • 사용자는 클라이언트 애플리케이션으로부터 리다이렉트되어 인증 서버에서 로그인 및 권한 부여, 인가 코드를 받는다.
    • 그런 다음 클라이언트는 인가 코드와 함께 인증 서버에 액세스 토큰을 요청하고 이를 교환한다.
  2. Implicit Grant (암시적 방식)

    • 웹 브라우저 자바스크립트 기반의 클라이언트 애플리케이션에서 사용된다.
    • 리소스가 제한된 상황에서 간략화된 인증방식
    • Access 토큰을 직접 요청하며 인가 코드를 교환하지 않고 사용자가 인증 서버에서 로그인하여 권한을 부여받은 후 클라이언트가 액세스 토큰을 받는다.
    • 간편하지만 보안성이 낮을 수 있으므로 사용에 주의가 필요하다.
  3. Client Credentials Grant (클라이언트 자격 증명 방식)

    • 이 방식은 클라이언트 애플리케이션이 자체적으로 액세스 토큰을 요청할 때 사용
      • 리소스 오너와 클라이언트가 동일한 개체일 때 사용
    • 사용자의 개인 정보와는 관련 없고 클라이언트를 인증하여 액세스 토큰을 발급받는다.
    • 서버 간 통신이 필요한 경우나 백그라운드 작업을 수행하는 서버 애플리케이션에서 사용할 수 있다.
  4. Password Credentials Grant (암호 자격 증명 방식)

    • 이 방식은 사용자의 로그인 정보(아이디와 비밀번호)를 사용하여 직접 액세스 토큰을 요청할 때 사용
    • 클라이언트가 사용자의 암호를 알고 있어야 해서 보안이 높지 않을 수 있다.
    • 일부 특수한 경우에만 사용한다.
    • 일반적으로 권장되지 않는 방식이다.

OAuth와 JWT

중간 중간 Access 토큰과 Refresh 토큰이 계속 나오니 JWT가 안 나올 수 없다.

OAuth2.0에선 Access 토큰을 이용해 클라이언트가 리소스 서버로 접근 가능한데 이때 Access 토큰으로 사용하는 것인 JWT이다. JWT의 내용을 간략히 해 보자면

  • 토큰 기방 방식의 인증 절차
  • 내부에 Claim이 있어 별도의 저장소 없이 자체적으로 인증 가능
  • 서명이 들어있어 무결성 검증과 유효성 검증이 가능하다.
  • JSON 포멧 사용으로 확장성이 좋다.

이런 것을 적용한다면 Oauth2.0에서 권한 부여를 위한 코드 승인을 할 때 권한 부여 코드로 Access 토큰을 이용하는데 이때 이 토큰을 JWT를 이용해 전달하며 이 JWT를 이용해서 리소스 서버에 접근 가능하다. 이런 것들이 위에서 적은 JWT의 장점 덕분이다.

이런 점 때문에 Access 토큰에 JWT를 사용한다고 한다.

적용

결국 이것을 Spring에 구현해야 하는데 이런 인증 인가 과정을 하나하나 구현하고 서버를 분리하는 것이 쉽지는 않다.

하지만 스프링이 무엇인가. 다 준비가 되어 있다고 한다. 바로 Spring Security!

Spring Security 사용하기

당연하지만 쓰고 싶다고 해서 바로 쓸 수 있는 것은 아니다. 아래의 과정에 따라 사용법을 알아보자.

  1. build.gradle에 security, oauth2-client 의존성 추가
dependencies {
    ...
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    ...
}
  1. 애플리케이션 설정하기
    • 애플리케이션마다 필요한 것이 다르므로 필요한 것들을 .xml 혹은 .properties 파일에 id, url 등을 설정한다.
    • Security Configuration의 설정으로 OAuth2.0 클라이언트와 리소스 서버의 설정을 컨트롤한다.
  2. 클라이언트 설정
    • Authorization Server
      • 인증 서버를 설정하고 권한 부여 요청이 들어올 때 필요한 요소들을 제공할 수 있도록 구성한다.
    • Resource Server
      • 마찬가지로 Access 토큰으로 인증을 하며 정보를 요청할 때 필요한 정보를 제공할 수 있도록 구성한다.
  3. OAuth2.0에서 제공하는 처리 방식 4가지 중 한 가지를 적절히 선택한다.

결론

Oauth는 인증과 인가를 위한 프로토콜이다.

가장 많이 사용하는 버전은 2.0이며 4가지의 방식 중 하나를 선택해 동작하므로 4가지의 동작 중 필요한 방식을 선택해서 사용한다.

Spring에선 Spring Security를 이용해 구현한다.

  • 아직 스프링이 미숙하다 보니 이 부분은 많이 어려웠다..
profile
프로그래밍을 잘하고 싶어요..

0개의 댓글