ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Auth] oAuth2 proxy + Okta 연동하기 예제
    [IT] 공부하는 개발자/Open Source 2023. 6. 11. 14:47

     

     


     

    Oauth2 proxy 란?

    백엔드 서비스에 대한 인증 및 권한 부여를 처리하는 중간 프록시 서버

    OAuth 2.0 인증을 사용한다.

     

     

    어떤 역할을 수행할까요?

    - 사용자 인증

    - Provider 에 요청해 액세스 토큰을 발급

     

     

    아키텍처

     

    AS-IS:

    사용자에게서 들어온 요청을 바로 업스트림(실제 서비스)으로 보낸다

     

    TO-BE:

    사용자에게서 들어온 요청은 업스트림으로 가기 전에 OAuth2 reverse proxy를 거친다. (중간에 Nginx를 한 번 더 거쳐도 되고, 거치지 않아도 된다.)

    리버스 프록시 서버는 요청이 액세스 토큰을 가지고 있다면 업스트림으로 패스시켜 주고,

    액세스 토큰이 없다면 Auth provider를 호출해 유저의 접근 여부를 확인, 액세스 토큰을 발급받아 유저에게 부여한다.


     

    Flow

    인증이 제대로 처리되려면 다음 과정을 순서대로 수행해야 한다.

     

    1. 인증 Provider에 Application 정보를 등록하고, Credential을 발급받는다.
    2. oAuth2 proxy 컨테이너를 띄울 때 주입할 인수 정보를 Dockerfile에 포함시켜 작성한다. 정보를 주입하는 방법은 다음 3가지가 있다.
      1. 컨테이너를 실행할 때 커맨드라인 명령어로 주입한다.
      2. 'OAUTH2_PROXY_'로 시작하는 환경 변수를 만들어 컨테이너 안에 세팅한다.
      3. Config 파일을 만들고 그 안에 작성한다.

        설정은 1번 > 2번 > 3번 순으로 우선순위를 갖는다. 예를 들어 redirect-url을 세팅하기 위해 컨테이너 안에 OAUTH2_PROXY_REDIRECT_URL 환경변수를 만든다면, config 파일 안에 redirect_url= 정보가 작성되어 있어도 config 파일 정보는 오버라이드 된다. 
    3. oAuth2 proxy 컨테이너를 실행하고, request를 보낸다.

     

    1번의 Auth provider는 Okta를 사용한다고 가정하고, 실제로 config 파일을 작성해 보자..!

     


    Example

    oauth2-proxy.cfg

    # OAuth2 Proxy Config File
    
    # oAuth2 proxy port
    http_address = "0.0.0.0:4180"
    
    # 인증 요청을 완료한 후 요청을 redirect 해줄 URL
    redirect_url = "https://internalapp.yourcompany.com/oauth2/callback"
    
    # Access token 을 가지고 있는 요청을 패스시켜줄 업스트림
    upstreams = [
        "http://127.0.0.1:8080/"
    ]
    
    # pass X-Forwarded-User, X-Forwarded-Groups, X-Forwarded-Email, X-Forwarded-Preferred-Username 값을 헤더로 Upstream 에 넘겨줄지 여부
    pass_user_headers = true
    
    
    # 이메일 주소가 허용된 도메인인지 검증을 추가할 수 있다. 검증하지 않으려면 "*" 을 입력한다.
    email_domains = [
        "yourcompany.com"
    ]
    
    # provider 측에서 발급받은 credential 을 넣는다.
    oidc_issuer_url = "https://yourcompany.okta.com/oauth2/default"
    client_id = "123456.apps.googleusercontent.com"
    client_secret = ""
    skip_provider_button = true # Okta 인증 페이지로 리다이렉팅하기전에 사용자에게 물어볼지 말지 여부
    
    # scope 정보, provider 에서 지원하는 유저 인증 정보 범위 (id token 을 받기 위해 openid 추가)
    scope = "openid email groups"
    # scope 에 groups 가 포함되어 있는 경우에만 유효하다. 받고자 하는 groups claim 의 이름을 지정하기 위한것.
    oidc_groups_claim = "groups"
    
    
    ## 쿠키 정보
    cookie_secret = "<16, 24, or 32 bytes>"
    cookie_expire = "24h0m0s"
    
    # 유저 response 로 X-Auth 헤더 정보를 담아 보낸다. 디버깅용으로 유용함
    set_xauthrequest = true
    
    # oidc 정보

    Cookie secret 은 임의의 값을 만들어서 넣으면 된다. 나는 bash shell에 다음 커맨드를 입력해서 만들었다.

    dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo

     

     

    Dockerfile

    FROM quay.io/oauth2-proxy/oauth2-proxy:v7.2.0
    
    ADD oauth2-proxy.cfg /etc/oauth2-proxy/oauth2-proxy.cfg
    
    CMD ["--config", "/etc/oauth2-proxy/oauth2-proxy.cfg"]

     

    도커파일을 빌드한 후 실행한다.

    그리고 localhost:4180으로 접속하면, oAuth2 proxy 가 Okta 의 로그인창을 보여줄 것이고, 내가 Okta 에서 로그인하고나면, redirect_url 로 로그인이 될 것이다. 그리고 크롬창에서 개발자도구로 쿠키를 확인해보면 액세스 토큰이 생긴것을 볼 수 있다. 이제 액세스 토큰이 있으면 localhost:4180 으로 접속해도 8080의 Upstream 앱으로 프록시된다.

     

     


    Open id connect

    # id token 받기

     

    Authorization 까지만 구현한다면, 위의 과정까지로 단순하다. 

    Open id connect (oidc) 방식을 채택한다면 유저 정보인 Id token을 발급받을 수 있고, 한 단계 더 나아가 Authentication까지 가능하다. 나는 Authentication 까지 도전했다. Okta에서 유저 관련 정보 (토큰)을 받아서 Upstream app 안에서 역할 기반의 액세스 제어를 하고 싶었다.

     

    Okta 에 인증을 요청할 때에 response_type이라는 parameter를 통해 내가 어떤 타입의 토큰을 발급받을 것인지 선택하게 되는데, oAuth2 proxy는 무조건 response_type=code로 요청이 나간다. 그래서 처음에는 id token을 못 받는 건가 싶었지만...

     

     

    그렇지 않다! response_type=code 일지라도 scope에 openid 가 포함되어 있다면, id token을 받을 수 있다. response_type 은 Authorization 단계에서 사용할 토큰의 타입을 정의하는 것이고, 그 후에 token request로 받을 정보는 "scope"에 정의하는 것이다.

     

    위의 oauth2-proxy.cfg example에서 scope = "openid email profile...."에 openid를 포함하고 있기 때문에...  id token을 받을 수 있다!

     

     

    response_type과 scope 가 어떻게 넘어가느냐에 따라서, 우리가 받는 인증/토큰 타입이 달라진다. 그것은... 이 아티클에 너무 잘 정리되어 있어서 참고하면 좋다. OIDC 인증 플로우에 대해 제대로 알 수 있다: https://darutk.medium.com/diagrams-of-all-the-openid-connect-flows-6968e3990660

     

    Diagrams of All The OpenID Connect Flows

    Introduction

    darutk.medium.com

     

     

     

     

     


     

    # Application groups 받기

    위의 설정 파일을 보면, 나는 scope = "openid email groups"를 설정했다. id token에 유저가 소속된 그룹 정보를 포함해 받고 싶었기 때문이다. 그런데 실제로 돌아온 리스폰스 헤더를 보니... 일부 그룹만 있고 내가 찾는 그룹 정보가 없는 것이었다. 

    왜 그런고 하면, 일단 Okta group 은 소스타입이 여러 개가 있다는 것을 알아야 한다.

     

     

    https://help.okta.com/en-us/Content/Topics/users-groups-profiles/usgp-group-types.htm

     

    Okta group source types | Okta

     

    help.okta.com

     

    기본 Okta 그룹 Okta를 애플리케이션 또는 기타 리소스에 연결하기 전에 Okta 조직 에서 그룹을 생성할 수 있습니다 . 기본 그룹인 모두는 Okta 조직 의 모든 사용자를 포함합니다 .
    Okta 그룹을 관리하려면 Okta Admin Console 에 로그인 하고 디렉터리 > 그룹을 클릭합니다 .
    Okta 관리자 그룹에는 조직의 모든 관리자가 포함됩니다.
    Active Directory 그룹 AD(Active Directory)는 그룹의 가장 일반적인 소스입니다. 상당한 규모의 거의 모든 비즈니스에서 AD 인스턴스를 사용하여 사용자를 관리합니다. Okta AD 에이전트를 사용하여 AD 인스턴스를 Okta 와 통합 할 수 있습니다 .
    Okta는 여러 도메인의 구성원을 포함하는 도메인 로컬 그룹을 지원하지 않습니다. 교차 도메인 멤버십이 있는 범용 보안 그룹은 도메인 간에 양방향 트러스트가 설정된 경우 지원됩니다. 유니버설 보안 그룹은 포리스트 간 구성원을 지원하지 않습니다.
    LDAP 그룹 Okta LDAP 에이전트를 사용하여 LDAP 호환 Windows 및 Unix 서버에서 그룹을 가져올 수 있습니다 .
    애플리케이션 그룹 일부 애플리케이션에는 Okta 로 가져올 수 있는 그룹이 있습니다 . 이러한 그룹을 가져오는 기능은 API를 통해 그룹에 액세스할 수 있는지 여부와 애플리케이션이 Okta 와 통합되었는지 여부에 따라 다릅니다 . 다음은 그룹 가져오기를 지원하는 몇 가지 응용 프로그램입니다.
    • 상자
    • 구글 앱스
    • 지라
    • 마이크로소프트 오피스 365
    • 근무일

    이렇게 4가지 소스타입이 있는데.... 나는 active_directory 폴더에 있는 그룹 정보를 원하는데, Okta는 default로 기본 옥타 그룹만 넘겨주게 설정이 되어 있다는 것.... 옥타에서만 관리하는 그룹 정보가 아니라, 동적으로 관리되는 유니버설 보안 그룹을 원한다!!

    방법은 Okta에 접속하여 group claim에 AD 그룹도 담기도록 설정을 하는 것이다.

    아래 옥타 고객센터의 설명을 잘 읽고 따라 했더니, AD 그룹 정보가 claim으로 포함되어 넘어왔다.

    custom group claim 명은 보통 "groups"로 쓰니까 그대로 두면 되는데... 만약 다른 걸로 쓰고 있다면 그걸로 꼭 바꿔줘야 한다. (내가 oAuth2 proxy 설정파일에 작성한 바로 그 group claim 명으로..!)

     

    https://support.okta.com/help/s/article/Can-we-retrieve-both-Active-Directory-and-Okta-groups-in-OpenID-Connect-claims?language=en_US 

     

    Can We Retrieve Both Active Directory and Okta Groups in OpenID Connect Claims?

    Navigate to Directory > Profile Editor > Users (tab) > Directories (filter) and copy the variable under the name of the directory to be used. Navigate to Admin > Applications > OpenID Connect application > Sign On tab > OpenID Connect ID Token Select Edit,

    support.okta.com

     

     

     

     


     

    oauth2-proxy 깃허브 및 공식 문서에서 더 많은 정보를 얻을 수 있다.

     

     

     

    https://oauth2-proxy.github.io/oauth2-proxy/docs/

     

    Installation | OAuth2 Proxy

    1. Choose how to deploy:

    oauth2-proxy.github.io

     

     

     

     

     

    reference

     

    https://github.com/oauth2-proxy/oauth2-proxy

     

     

     

     

    댓글

Copyright in 2020 (And Beyond)