공부기록/Spring

[Spring Security] OAuth2

taecode 2025. 2. 10. 20:25

Credential : 자격 증명을 위한 정보(비밀번호)

 

지금까지는 크리덴셜을 우리 DB에 저장하고 관리했지만 OAuth2는 외부에서 관리한다.

 

 

기존 서비스의 크리덴셜 저장 아키텍처

 

 

 

써드 파티 애플리케이션의 크리덴셜을 저장하는 아키텍처

 

 

- 제 3사의 크리덴셜을 우리 서버에 보관하는 것은 위험함.

 

OAuth2 는 특정 애플리케이션에서 사용자의 인증을 직접 처리하는 것이 아니라 사용자 정보를 보유하고 있는 신뢰할 만한 써드 파티 애플리케이션에서 사용자의 인증을 대신 처리해 주고 Resource에 대한 자격 증명용 토큰을 발급한 후, Client가 해당 토큰을 이용해 써드 파티 애플리케이션의 서비스를 사용하게 해주는 방식이다.

 

써드 파티 애플리케이션의 크리덴셜을 저장하지 않는 아키텍처

 

서비스 애플리케이션에 구글의 크리덴셜이 직접적으로 제공되지 않기 때문에 서비스 애플리케이션에서 사용하는 크리덴셜 저장소에 저장될 필요가 없으므로 크리덴셜을 이중으로 관리하지 않아도 된다. 관리하는 크리덴셜이 줄어드는 것은 보안성도 향상된다는 의미.

 

 

OAuth 2를 사용하는 애플리케이션 유형

1️⃣ 써드 파티 애플리케이션에서 제공하는 API의 직접적인 사용

 - Google, Github, Facebook 같은 신뢰할만한 써드 파티 애플리케이션에서 제공하는 API를 직접적으로 사용하는 애플리케이션을 구현하는데 OAuth 2를 사용할 수 있다.

 - 사용자가 OAuth2 인증 프로토콜을 이용해 써드 파티 애플리케이션에 대한 인증에 성공하면 써드 파티 애플리케이션에서 제공하는 API를 활용한 커스텀 서비스를 제공한다.

 

 

2️⃣ 추가적인 인증 서비스 제공 용도

 - 써드 파티 애플리케이션의 서비스를 이용하는 것뿐만 아니라 추가적인 인증 서비스를 제공하기 위한 용도로 사용하기 위함.
 - 일반적으로 제공하는 아이디/패스워드 로그인 인증 이외에 OAuth 2를 이용한 로그인 인증 방법을 추가적으로 제공하는 것.

 - 특정 서비스를 제공하는 애플리케이션에서 사용자의 크리덴셜을 남기고 싶지 않을 경우 OAuth 2 로그인 인증 방법으로 로그인 하면 된다.

 

OAuth2의 동작 방식

 

OAuth 2 인증 컴포넌트(Component, 구성요소) 들의 역할

 

  • Resource Owner : 사용하고자 하는 Resource의 소유자
     - Google 등의 서비스를 이용하는 사용자

  • Client
    - Resource Owner 를 대신해 보호된 Resource에 액세스하는 애플리케이션
    - 나를 대신해서 인증서버에 요청을 함.( 우리가 만든 애플리케이션 )
    - 어떤 서비스를 이용하고자 하는 쪽은 Client임.

  • Resource Server
    - Client의 요청을 수락하고 Resource Owner에게 해당하는 Resource를 제공하는 서버
    - OAuth 를 제공하는 벤더사는 OAuth만 처리하는 인증 서버가 따로 있음

  • Authorization Server
    - Resource Server에 접근할 수 있는 권한을 부여하는 서버.
    - Resource Owner가 인증에 성공하면 Authorization Server 는 Client에게 Access Token 형태로 Resource Owner의 Resouce에 접근할 수 있는 권한을 부여한다.


OAuth 2 컴포넌트 간의 상호 작용을 통한 인증 처리 흐름

  1. Resource Owner는 Client 역할을 하는 웹 애플리케이션에게 OAuth2 인증을 요청한다. 여기서 인증 요청은 Resource Owner가 인증을 할 수 있도록 Client인 웹 애플리케이션이 자체적으로 로그인 화면을 제공하는 것이 아닌, Resource Owner는 자신의 계정 정보를 관리하고 있는 써드 파티 애플리케이션에 로그인하길 원하는 것으로, 이 요청을 Client인 웹 애플리케이션에 전송하는 것이다.

  2. Client는 Resource Owner가 Resource Owner의 계정 정보를 관리하고 있는 써드 파티 애플리케이션에 로그인할 수 있도록 써드 파티 애플리케이션의 로그인 페이지로 리다이렉트 한다.

  3. Resource Owner는 로그인 인증을 진행하고 로그인 인증에 성공하면

  4. Authorization Server 가 Resource Owner의 로그인 인증이 성공적으로 수행되었음을 증명하는 Access Token을 Client에게 전송한다. Resource Owner에게 Access Token을 전송하는 것이 아니라 Client 애플리케이션에게 전송하는 것. Client는 Resource Owner를 대신해 Resource Owner의 Resource를 사용하는 대리인 역할이기 때문

  5. Access Token을 전달받은 Client는 이제 Resource Owner의 대리인 역할을 수행할 수 있게 되었으므로, Resource Server에게 Resource Owner 소유의 Resource를 Client에게 전송한다.

 - 핵심 : 어떤 Resource를 소유하고 있는 Resource Owner를 대신하는 누군가(Client)가 Resource Owner의 대리인 역할을 수행한다는 것.

 

 

 

 

- Redirect 시키는 주체가 우리 서버여야함( React에서 바로 x )

- 소셜 로그인은 비밀번호 변경할 수 없음 (크리덴셜이 우리한테 없으니까)

 

 

 

OAuth 2 인증 프로토콜에서 사용되는 용어

 

Authorization Grant

  • Authorization Grant는 Client 애플리케이션이 Access Token을 얻기 위한 Resource Owner의 권한을 표현하는 크리덴셜을 의미한다.
  • Client가 Access Token을 얻기 위한 수단이라고 생각하면 되고, 네 가지 타입이 있다.
    - Authorization Code
    - Implicit Grant Type
    - Client Credentials
    - Resource Owner Password Credentials

Access Token

 - 클라이언트가 Resource Server에 있는 Resource에 액세스 하기 위해 사용하는 자격 증명용 토큰
 - Authorization Code와 Client Secret을 이용해 Authorization Server로부터 전달받은 Access Token으로 자격을 증명하면 Resource server에 접근할 수 있다.

 

Scope

 - 주어진 액세스 토큰으로 어디까지 접근할 수 있는지의 범위

 

 

Authorization Grant의 유형

 

1️⃣ Authorization Code Grant : 권한 부여 승인 코드 방식

 - 권한 부여 승인을 위해 자체 생성한 Authorization Code를 전달하는 방식으로, 가장 많이 쓰이고 기본이 되는 방식

 - Refresh Token 사용 가능

 - 권한 부여 승인 요청 시 응답 타입(response_type)을 code로 지정하여 요청

 

  1. Resource Owner는 소셜 로그인 버튼을 누르는 등의 서비스 요청을 Client(애플리케이션)에게 전송
  2. Client는 Authorization Server에 Authorization Code를 요청합니다. 이때 미리 생성한 Client ID, Redirect URI, 응답 타입을 함께 전송
  3. Resource Owner는 로그인 페이지를 통해 로그인을 진행
  4. 로그인이 확인되면 Authorization Server는 Authorization Code를 Client에게 전달 (이 전에 요청과 함께 전달한 Redirect URI로 Code를 전달)
  5. Client는 전달받은 Authorization Code를 이용해 Access Token 발급을 요청,  Access Token을 요청할 때 미리 생성한 Client Secret, Redirect URI, 권한 부여 방식, Authorization Code를 함께 전송
  6. 요청 정보를 확인한 후 Redirect URI로 Access Token을 발급
  7. Client는 발급받은 Access Token을 이용해 Resource Server에 Resource를 요청
  8. Access Token을 확인한 후 요청받은 Resource를 Client에게 전달

 

 

2️⃣ Implicit Grant : 암묵적 승인 방식

 - 별도의 Authorization Code 없이 바로 Access Token을 발급하는 방식
 - 자격증명을 안전하게 저장하기 힘든 Client(자바스크립트 등 스크립트 언어를 사용하는 브라우저)에게 최적화된 방식

 - Refresh Token 사용이 불가능하며, 이 방식에서 Authorization Server는 Client Secret을 통해 클라이언트 인증 과정을 생략

 - 보통 React에서 바로 요청하거나 Severless 일때 사용

 - Authorization Code 없음

 - 권한 부여 승인 요청 시 응답 타입(response_type)을 token으로 지정하여 요청

 

 

 

 

  1. Resource Owner는 소셜 로그인 버튼을 누르는 등의 서비스 요청을 Client(애플리케이션)에게 전송
  2. Client는 Authorization Server에게 접근 권한 요청
  3. 요청과 함께 미리 생성한 Client ID, Redirect URI, 응답 타입을 전송합니다. (Authorization Code를 획득하기 위한 요청이 아님)
  4. Resource Owner는 로그인 페이지를 통해 로그인을 진행
  5. 로그인이 확인되면 Authorization Server는 Client에게 Access Token을 전달
  6. Client는 Access Token을 이용해 Resource Server에게 Resource를 요청
  7. Access Token을 확인한 후 요청받은 Resource를 전달

 

 

 

 

 

3️⃣ Resource Owner Password Credential Grant : 자원 소유자 자격 증명 승인 방식

  • 간단하게 로그인 시 필요한 정보(username, password)로 Access Token을 발급받는 방식입니다. 자신의 서비스에서 제공하는 애플리케이션의 경우에만 사용되는 인증 방식으로, Refresh Token의 사용도 가능
  • 예를 들어 네이버 계정으로 네이버 웹툰 애플리케이션에 로그인, 카카오 계정으로 카카오 지도 애플리케이션에 로그인하는 경우가 Resource Owner Password Credential Grant에 해당
  • Authorization Server, Resource Server, Client가 모두 같은 시스템에 속해 있을 때만 사용이 가능
    (ex. Naver, Naver Webtoon, Naver Blog 등등 )

 

 

  1. Resource Owner는 로그인 버튼을 누르는 등의 서비스 요청을 Client(애플리케이션)에게 전송,  이때 로그인에 필요한 정보(Username, Password)를 이용해 요청
  2. Client에서는 Resource Owner에게서 전달받은 로그인 정보를 통해 Authorization Server에 Access Token을 요청하고 미리 생성한 Client ID, 권한 부여 방식, 로그인 정보를 함께 전달
  3. 요청과 함께 온 정보들을 확인한 후 Client에게 Access Token을 전달
  4. Client는 Access Token을 이용하여 Resource Server에게 Resource를 요청
  5. Access Token을 확인한 후 요청받은 Resource를 전달

 

 

4️⃣ Client Credentials Grant : 클라이언트 자격 증명 승인 방식

  • Client 자신이 관리하는 Resource 혹은 Authorization Server에 해당 Client를 위한 제한된 Resource 접근 권한이 설정되어 있는 경우 사용할 수 있는 방식이다.
  • 이는 자격 증명을 안전하게 보관할 수 있는 Client에서만 사용되어야 하며, Refresh Token의 사용은 불가능하다.

 

 

 

 

총평 : OAuth는 어렵다..