ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OAuth 2.0 과 Spring Security
    Spring/Security 2023. 9. 30. 14:31
    728x90

    OAuth는 사용자가 제3자 애플리케이션에 대한 액세스 권한을 부여할 수 있도록 중간 매개체 역할을하는 보안 프레임워크로

    웹 및 모바일 애플리케이션에서 사용자 인증 및 권한 부여를 위한 개방형 표준 프로토콜이다.

     

    이를 통해 사용자는 자신의 계정 정보를 직접 공유하지 않고도 제 3 애플리케이션에 대해 제한된 액세스 권한을 제공할 수 있다.

    스프링 시큐리티는 스프링 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크로 인증(Authenticate)과 인가(Authorize)를 담당하는 프레임워크를 말한다.

     

    스프링 시큐리티에서는 주로 서블릿 필터(filter)와 이들로 구성된 필터체인으로의 구성된 위임모델을 사용하고 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 가 보안 관련 로직을 작성하지 않아도 된다는 장점이 있다.

     

    참고 OAuth2.0 동작 방식의 이해

    이번 포스팅은 OAuth2.0과 Spring Security에 대해 알아보고 이를 적용해 소셜 로그인을 진행하는게 목표이다.


    OAuth 2.0

    주요 용어

    Authentication | 인증
    인증, 접근 자격이 있는지 검증하는 단계

    Authorization | 인가
    인가, 자원에 접근할 권한을 부여하는 것으로 인가가 완료되면 클라이언트에게 리소스 접근 권한이 담긴 Access Token이 부여된다.

    Access Token
    리소스 서버에게서 리소스 소유자의 보호된 자원을 획득할 때 사용되는 만료 기간이 있는 Token

    Refresh Token
    Access Token 만료시 이를 갱신하기 위한 용도로 사용하는 Token으로 Access Token보다 유효 기간이 길다.

    OAuth 역할 구성

    클라이언트

    제 3자 애플리케이션 또는 서비스로 클라이언트는 사용자의 리소스에 액세스하기 위해  
    OAuth 인증 프로세스를 시작하고 인증 서버와 통신한다.

    리소스 소유자

    클라이언트 애플리케이션의 사용자 또는 소유자로 리소스 소유자는 자신의 리소스에 대한 액세스 권한을 부여한다. 
    (ex. 사용자 프로필, 사진 ..)  
    - OAuth2 프로토콜 흐름에서 클라이언트를 인증하는 역할을 수행 
    - 인증이 완료되면 권한 획득 자격을 클라이언트에게 부여  
    개념적으로는 리소스 소유자가 자격을 부여하는 것이지만 일반적으로 권한 서버가 리소스 소유자와 클라이언트 사이에서 중개 역할을 수행한다.

    리소스 서버

    클라이언트가 액세스하려는 실제 리소스가 있는 서버로 
    리소스 서버는 클라이언트에게 리소스에 대한 액세스 권한이 있는지 확인하고 해당 리소스를 제공한다.

    인증 서버

    인증 서버는 클라이언트와 리소스 서버 간의 신뢰 관계를 설정하고 
    클라이언트의 인증 및 권한 부여를 처리해 액세스 토큰을 발급한다.

    OAuth 프로세스 단계

    1. 클라이언트 등록
      • 클라이언트는 인증 서버에 등록하여 클라이언트 식별자와 비밀 키를 받는다.
    2. 사용자 리다이렉션
      • 클라이언트는 사용자를 인증 서버로 리다이렉션 하는 과정이 필요한데
        이 때 클라이언트는 인증 요청에 대한 권한 범위와 리다이렉션 URI를 전달한다.
    3. 사용자 인증
      • 사용자는 인증 서버에 로그인하여 자신의 자격 증명을 제공한다.
    4. 권한 부여 동의
      • 사용자는 클라이언트가 요청한 권한 범위에 대한 동의 여부를 결정

    권한 부여(인증) 방식 종류

    Authorization Code Grant | 권한 부여 승인 코드 방식

    권한 부여 승인을 위해 자체 생성한 Authorization Code를 전달하는 형태로
    인증의 기본이 되는 방식이다.

     

    간편 로그인 기능에서 사용 되는 방식으로 클라이언트가 사용자를 대신하여 특정 자원에 접근을 요청할 때 사용한다.


    일반적으로 타사의 클라이언트에게 보호된 자원을 제공하기 위한 인증에 사용되며 Refresh Token 사용이 가능하다.

     

    • 권한 부여 승인 요청 시 response_type을 code로 지정해 요청한다.
    • 이후 클라이언트는 권한 서버에서 제공하는 로그인 페이지를 브라우저로 띄워 출력한다.
    • 이 페이지를 통해 사용자가 로그인을 하면 권한 서버는 권한 부여 승인 코드 요청 시 전달받은 redirect-url로 Authorization-Code를 전달한다.
    • Authorization-Code는 권한 서버에서 제공하는 API를 통해 Access Token으로 교환한다.

    Implicit Grant │ 암묵적 승인 방식

    자격 증명을 안전하게 저장하기 힘든 클라이언트(스크립트 언어를 사용한 브라우저)에 최적화된 방식으로 암묵적 승인 방식에서는 권한 부여 승인 코드 없이 바로 Access Token이 발급된다.

     

    Access Token이 바로 전달되므로 만료 기간을 짧게 설정해 위험을 줄일 필요가 있다.

     

    Refresh Token 사용이 불가능하며 권한 서버는 client-secret을 사용해 클라이언트를 인증하지않는다.

    • Access Token 획득을 위한 절차 간소화 -> 응답성, 효율성 증가
    • Access Token URL로 전달 -> 보안 취약

     

    권한 부여 승인 요청시 response-type을 token으로 설정하여 요청한다.
    이 후 클라이언트는 권한 서버에서 제공하는 로그인 페이지를 브라우저를 띄워 출력하고 작업이 완료되면 권한 서버는 Access-Token을 redirect-url로 전달한다.

    Resource Owner Password Credentials Grant

    자원 소유자 자격증명 승인 방식

    username, password로 Access Token을 받는 방식으로 클라이언트가 내부 프로그램일 경우에만 이 방식을 적용한다.
    (직접 운영하는 서비스에서 제공하는 애플리케이션일 경우에만 사용)

     

    중요 포인트로 이 방식은 권한 서버, 리소스 서버, 클라이언트가 모두 같은 시스템에 속해 있을 때 사용되어야 하는 방식이다.

    Client Credentials Grant │클라이언트 자격증명 승인 방식

    클라이언트의 자격 증명만으로 Access Token을 획득하는 방식
    OAuth2의 권한 부여 방식중 가장 간단한 방식으로 클라이언트 자신이 관리하는 리소스 혹은 권한 서버에 해당 클라이언트를 위한 제한된 리소스 접근 권한이 설정되어 있는 경우 사용된다.

     

    해당 방식은 자격 증명을 안전하게 보관할 수 있는 클라이언트에서만 사용되어야 하고 Refresh Token 사용이 불가하다.

     


    Spring Security

    주요 용어

    Principal | 접근 주체
    Principal는 시스템 또는 애플리케이션에 접근하는 개체를 나타내고 주로 사용자를 의미하며 인증된 사용자의 정보를 포함한다.

    (Ex. 사용자의 아이디, 이메일, 권한 등의 정보가 접근 주체에 속할 수 있음)

    Authentication | 인증
    인증은 접근 주체가 자신의 신원을 증명하고 확인하는 프로세스를 의미한다.
    사용자가 제공한 아이디, 비밀번호, 인증 토큰 등을 검증하여 사용자 신원을 확인한다.
    -> 누구인지

    Authorization | 인가
    인가는 인증된 접근 주체에게 특정 리소스 또는 기능에 대한 권한을 부여하는 프로세스를 의미하며
    인가는 접근 주체가 수행할 수 있는 작업의 범위를 정의하는 권한을 관리한다.

    (Ex. 특정 사용자가 특정 페이지에 접근하거나 특정 작업을 수행할 수 있는지 여부를 결정하는게 인가의 역할) -> 무엇을 할 수 있는지

    Authority | 권한
    권한은 인증된 접근 주체가 특정 리소스 또는 기능에 대해 수행할 수 있는 권한을 나타낸다.
    역할(Role)이라고도 불리고 사용자에게 할당되어 특정 작업을 수행할 수 있는 권한을 부여한다.
    (Ex. ‘관리자’ 권한을 가진 사용자는 관리자 전용 기능에 액세스 할 수 있다.)

    -> 인가 과정에서 해당 리소스에 대해 제한된 최소한의 권한을 가졌는지 확인한다.

    스프링 시큐리티 구조 프로세스

    시큐리티 필터 체인(Security Filter Chain) 은 스프링 시큐리티의 핵심으로 다양한 보안 필터들이 연결되며 각 필터는 특정 보안 작업을 수행하고, 요청 및 응답을 처리한다.


    필터 체인은 웹 애플리케이션의 보안 계층을 구성하며, 인증 및 인가 프로세스가 필터 체인에서 이루어진다.

     

    1. Http Request 수신
    Spring Security는 필터로 동작을 한다. 
    요청이 들어오면, 인증과 권한을 위한 필터들을 통하게 된다.  
    유저가 인증을 요청할때 필터는 인증 메커니즘과 모델을 기반으로한 필터를 통과한다.
    
    - HTTP 기본 인증을 요청하면 BasicAuthenticationFilter를 통과한다. 
    - HTTP Digest 인증을 요청하면 DigestAuthenticationFilter를 통과한다. 
    - 로그인 폼에 의해 요청된 인증은 UseerPasswordAuthenticationFilter를 통과한다.
    1. AuthenticationFilter
    - Request 요청을 가로채고 인증 매니저를 통해 인증을 진행한다. 
    - 인증 매니저로부터 받은 인증 결과를 처리한다. 
    - 인증 실패일 경우 실패한 이유에 따라 에러 처리를 수행한다. 
    - 성공할 경우 사용자 세션을 생성하거나 리다이렉션 등의 후 처리를 수행할 수 있다.
    1. UsernamePasswordAuthenticationToken
    사용자가 제공한 아이디와 비밀번호등을 인증 정보를 저장하고 
    입력된 사용자 정보에서 아이디와 비밀번호를 추출해 인증 매니저(Authentication Manager)로 전달한다.  
    인증 성공시 인증된 사용자의 정보를 담은 'Authentication' 객체로 업데이트 되고 
    해당 객체는 보안 컨텍스트에 저장되어 인증된 사용자의 정보를 유지한다.
    1. AuthenticationProvider
    사용자가 제공한 인증 정보를 검증하는 단계로 사용자의 아이디 비밀번호를 확인하고 
    필요에 따라 추가적인 요소를 검증할 수 있다.
    
    인증이 성공한 경우 Authentication 객체를 생성해 인증된 사용자의 정보를 포함시킨다. 
    인증이 실패한 경우 ‘AuthenticationException’ 예외를 던지거나 null을 반환 
    ( 아이디 비밀번호, 토큰등 다양한 인증 방식 처리가 가능하다.)
    1. UserDetailsService
    사용자 정보를 로드하는 인터페이스로 식별자를 기반으로 상세 정보를 로드한다. 
    로드한 정보를 바탕으로 인증 매니저(AuthenticationManager)가 사용자 인증을 수행한다.  
    UserDetailsService는 사용자 정보를 'UserDetails' 객체로 변환해 반환한다.
    1. UserDetails
    사용자의 인증 및 권한 정보를 담은 인터페이스로 
    구현 객체는 아이디, 비밀번호, 권한 등의 정보를 포함해 인증 매니저에게 반환된다.  
    개발자는 UserDetails 인터페이스를 구현하여 자신의 사용자 정보 객체를 생성하고, 
    해당 객체에 사용자의 아이디, 비밀번호, 권한 등을 설정할 수 있습니다. 
    스프링 시큐리티는 이러한 사용자 정보 객체를 활용하여 사용자 인증 및 권한 검사를 수행할 수 있다.
    1. SecurityContextHolder
    SecurityContextHolder는 스프링 시큐리티에서 현재 인증된 사용자의 보안 컨텍스트를 관리하는 클래스로 
    SecurityContext 객체를 저장하고 제공하여 현재 실행 중인 스레드에서 
    사용자의 보안 정보에 접근할 수 있게 도와준다.  
    
    SecurityContext안에 Authentication 객체가 무엇인지에 따라 OAuth2 기반 객체인지, 
    일반 로그인 객체인지 판별할 수 있다.

     


Designed by Tistory.