OpenID Connect와 NGINX Plus를 사용하여 기존 애플리케이션의 사용자 인증하기

NGINX | 2016년 9월 07일

JWT 지원을 사용하여 기존 애플리케이션에 SSO 제공

[편집자 – 이 게시물에서는 인증을 위해 암시적 흐름을 지원하는 OpenID Connect 공급자와 NGINX Plus를 함께 사용하는 방법을 설명합니다. 기술적으로는 정확한 내용이지만, 참조 구현이 업데이트됨에 따라 일부 작업(예: 공개 키를 가져오기 위해 cron 사용)은 더 이상 필요하지 않습니다. 현재 구현에 대해서는 GitHub 저장소를 참조하세요.

In NGINX Plus R15 이상에서는 NGINX Plus를 OpenID Connect 인증 코드 흐름의 신뢰 당사자로 사용할 수도 있습니다.]

OAuth 2.0은 웹사이트와 애플리케이션의 인증 유연성과 사용자 경험을 크게 개선했습니다. 하지만 그 이름과 달리 OAuth 2.0 사양에서는 최종 사용자 신원 확인에 대해 거의 다루지 않으며 SSO(Single Sign-On)에 대해서는 전혀 언급하지 않습니다. 바로 이 지점에서 OpenID Connect가 필요합니다. OpenID Connect는 본질적으로 OAuth 2.0 액세스 토큰에 신원 정보를 담을 수 있게 해 주는, 그동안 빠져 있던 핵심 요소입니다.

OpenID Connect ID 토큰은 JSON Web Token(JWT) 사양을 준수합니다. JWT(“jot”으로 발음) 토큰은 크기가 작고 전달하기 쉬우며, ID 정보를 기술하기 위한 공통 핵심 스키마를 제공합니다. JWT의 가장 큰 장점은 API 클라이언트 인증부터 엔터프라이즈 애플리케이션용 SSO 제공에 이르기까지 거의 모든 ID 사용 사례에 적용할 수 있다는 것입니다. 실제로 Google Apps를 사용하는 많은 조직은 Google을 ID 공급자로 활용하여 엔터프라이즈 애플리케이션에 SSO를 제공할 수 있습니다. 그렇다고 해서 OpenID Connect와 JWT를 기존 웹 애플리케이션의 인증이나 SSO 제공에 사용할 수 없는 것은 아닙니다.

NGINX Plus R10 이상에는 기본 JWT 지원 기능이 포함되어 있어, NGINX Plus가 토큰을 검증하고 애플리케이션에서 쉽게 사용할 수 있는 방식으로 인증된 사용자의 ID 정보를 업스트림 요청에 추가할 수 있습니다. 이 블로그 게시물에서는 애플리케이션 자체를 변경하지 않고도 NGINX Plus의 기본 JWT 지원 기능을 사용하여 기존 애플리케이션에 SSO를 적용하는 방법을 설명합니다. 여기서는 Google을 ID 공급자로 사용하고, 간단한 웹사이트를 애플리케이션으로 사용합니다. 전체 흐름은 다음과 같습니다:

NGINX Plus는 Google 기반 SSO를 위해 OAuth 2.0 및 OpenID Connect를 사용하여 사용자 ID를 검증합니다

웹 애플리케이션에서 OpenID Connect 활성화

이 예제는 NGINX Plus 구성과 HTML 로그인 페이지라는 두 가지 구성 요소로 이루어져 있습니다.

NGINX Plus 구성

JWT를 검증하기 위한 NGINX Plus 구성은 매우 간단합니다.

server {    listen 80;
    root /var/www/public_html;

    location /private/ {
        auth_jwt "Google account" token=$cookie_auth_token;
        auth_jwt_key_file /etc/nginx/google_certs.jwk;
    }
}

The location 블록은 /private/로 시작하는 URL에 대한 모든 요청에 인증이 필요하도록 지정합니다. auth_jwt 지시문은 인증에 실패할 경우 401 응답과 함께 반환할 인증 영역을 정의하고, NGINX Plus가 요청 내에서 JWT를 찾을 위치를 지정합니다. 이 경우에는 auth_token이라는 쿠키에서 토큰을 찾습니다. 기본적으로 NGINX Plus는 클라이언트가 Bearer Token 형식의 JWT를 Authorization 헤더를 사용해 제공할 것으로 예상합니다. 이는 AJAX 애플리케이션 및 API 클라이언트에서 일반적으로 사용하는 방식이지만, 이 예시처럼 다른 HTTP 헤더, 쿼리 문자열 인수 또는 쿠키에서도 JWT를 가져올 수 있습니다.

The auth_jwt_key_file 지시문은 JWT의 서명 요소를 검증하는 방법을 NGINX에 알려 줍니다. 서명 검증을 통해 JWT가 Google에서 발급되었으며 발급 이후 수정되지 않았음을 확인할 수 있습니다. Google은 공개 키를 게시하고 정기적으로 갱신합니다. 최신 키 세트를 유지하려면 다음 cron(8) 작업 예시와 같이 crontab을 사용하여 매시간 키를 가져오세요.

0 * * * * wget https://www.googleapis.com/oauth2/v3/certs -O /etc/nginx/google_certs.jwk

HTML 기반 로그인 페이지

이 예제를 간단하고 이해하기 쉽게 유지하기 위해 전체 애플리케이션을 구축하지는 않습니다. 대신 다음과 같은 기본 HTML을 사용하여 로그인 페이지를 만듭니다. HTML 파일의 경로는 /var/www/public_html/index.html입니다(이 경로는 NGINX Plus 구성에서 정의한 root 경로와 일치합니다).

<html>
<head>
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <title>NGINX OpenID Connect demo</title>
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <meta name="google-signin-scope" content="profile email">
    <meta name="google-signin-client_id" content="client-ID.apps.googleusercontent.com"> <script src="/js.cookie.js"></script>
</head>
<body>
    <h2>NGINX OpenID Connect demo</h2>
    <hr/>
    <h3>Login with a Google account then visit the <a href="/private/">private area</a>.</h3>
    <table><tr><td>
    <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div></td>
    <script>
      function onSignIn(googleUser) {
        var profile = googleUser.getBasicProfile();
        Cookies.set('auth_token', googleUser.getAuthResponse().id_token);
        document.getElementById('google_signout').innerHTML = '<a href="#" onclick="signOut();"><img src="' + profile.getImageUrl() + '" width=32 height=32>Sign out</a>';
      };
      function signOut() {
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {
          Cookies.remove('auth_token');
          document.getElementById('google_signout').innerHTML = '';
        });
      }
    </script>
    <td><div id="google_signout"></div></td>
    </tr></table>
    <hr/>
</body>
</html>

다음 <head> 블록에서 두 가지 주요 종속성을 강조했습니다.

  • <meta name="google‑signin‑client_id"> 태그 – Google의 OAuth 2.0 JavaScript API를 사용하여 OAuth 2.0 최종 사용자 동의 및 인증 절차를 수행합니다. 이 API는 로그인 버튼을 제공하고 로그인 여부를 감지합니다. Google에서 웹사이트를 인증받으려면 OAuth 2.0 클라이언트 ID를 생성한 후, content 속성의 client-ID 자리 표시자를 해당 ID로 바꿔야 합니다. 새 OAuth 2.0 클라이언트 ID를 만드는 방법은 이 문서 하단의 부록을 참조하세요.
  • <script src="/js.cookie.js"> 태그 – OAuth 2.0 액세스 토큰에서 ID 토큰을 추출하고 웹사이트로 전송할 쿠키를 생성할 수 있는 쿠키 파서가 필요합니다. 이 작업은 Cookies.set 줄에서 수행하며, 이 태그에 포함된 JavaScript Cookie 라이브러리를 사용합니다.

이러한 요소를 모두 구성했으므로 이제 Google 로그인 메커니즘이 적용된 공개 홈페이지와 NGINX Plus로 보호되는 비공개 영역이 마련되었습니다. 비공개 영역에는 콘텐츠를 만들지 않았으므로 이 영역에 액세스하려고 하면 404 오류가 발생하는 것이 정상입니다.

추가 자료

고급 JWT 기능에 대한 자세한 내용은 JWT 및 NGINX Plus를 사용한 API 클라이언트 인증을 참조하세요. 이 문서에서는 JWT에서 얻은 사용자 ID 정보를 사용하여 인증된 요청을 프록시하고, JWT 클레임을 기록하며, 여러 ID 공급자를 지원하는 방법을 설명합니다.

NGINX Plus의 기본 JWT 지원 기능을 살펴보려면 지금 30일 무료 평가판을 시작하거나 문의해 주세요.

부록 – Google OAuth 2.0 클라이언트 ID 만들기

[편집자 – 게시 시점의 Google APIs GUI를 정확하게 반영하기 위해 최선을 다했지만, GUI는 매우 유동적이어서 메뉴 옵션과 위치가 변경될 수 있습니다. 이 지침을 참고하되 필요에 따라 현재 GUI에 맞게 조정하여 사용하세요.]

  1. 다음 주소에서 Google API 대시보드에 접속합니다. https://console.developers.google.com/apis/dashboard. 열리는 페이지는 이전의 Google API 사용 이력에 따라 달라집니다. 계정을 만들고 이용약관에 동의하는 등 이 안내에 나와 있지 않은 단계를 수행해야 할 수도 있습니다. 다음 스크린샷은 대시보드의 왼쪽 상단을 보여 줍니다. Google APIs 로고 오른쪽에 있는 단어를 클릭합니다(이전에 프로젝트를 만든 적이 있다면 프로젝트라는 단어 대신 해당 프로젝트 이름이 표시될 수 있습니다). 프로젝트 만들기를 선택합니다.
    Google OAuth 2.0 클라이언트 ID를 만들 때 API Manager 대시보드 왼쪽 상단의 Google APIs 로고 옆에 있는 드롭다운 메뉴에서 '프로젝트 만들기'를 선택합니다.
     
  2. 새 프로젝트를 만듭니다. 여기서는 새 프로젝트의 이름을 NGINX OpenID로 지정합니다. 만들기 버튼을 클릭하면 프로젝트가 생성되었다는 알림이 표시되기까지 몇 초 정도 걸릴 수 있습니다.
    Google OAuth 2.0 클라이언트 ID를 만들 때 새 프로젝트의 이름을 지정합니다.
     
  3. 프로젝트에 Google+ API를 사용 설정합니다. 이 API는 OAuth 2.0 인증 및 ID 서비스를 제공합니다. (API 관리자 대시보드가 창의 기본 영역에 아직 표시되지 않은 경우 화면 왼쪽의 탐색 영역에서 대시보드를 클릭합니다.) Google+ API를 사용 설정하려면 먼저 API 사용 설정 버튼을 클릭합니다.
    Google OAuth 2.0 클라이언트 ID를 만들 때 API Manager Dashboard 화면에서 ENABLE API 버튼을 클릭합니다.
     
  4. 클릭합니다. Google+ API(Social API 섹션에서)
     
  5. Click the 사용 설정 버튼을 클릭합니다.
     
  6. 프로젝트의 사용자 인증 정보를 만들려면 화면 왼쪽의 탐색 영역에서 사용자 인증 정보를 클릭한 다음 사용자 인증 정보 만들기 버튼을 클릭합니다. 드롭다운 메뉴에서 OAuth 클라이언트 ID를 선택합니다.
    Google OAuth 2.0 클라이언트 ID를 만들 때 생성할 사용자 인증 정보 유형으로 'OAuth 클라이언트 ID'를 선택합니다.
     
  7. Select the 웹 애플리케이션 라디오 버튼을 선택합니다. 승인된 JavaScript 원본 필드에 NGINX Plus가 설치된 호스트의 URL과 listen 지시문의 매개변수로 지정한 포트 번호를 웹 애플리케이션에 OpenID Connect 사용 설정에서 설명한 대로 입력합니다(예: mydomain.example.com:80). 이 예에서는 localhost를 사용하지만, 실제로는 NGINX Plus 인스턴스의 호스트 이름과 포트를 입력해야 합니다. 만들기 버튼을 클릭합니다(생성 프로세스를 시작하려면 두 번 이상 클릭해야 할 수도 있음).
     
  8. The OAuth 클라이언트 창이 열리고 클라이언트 ID와 클라이언트 보안 비밀번호가 표시됩니다. 클라이언트 ID를 앱에 있는 content 속성에 복사합니다. 해당 속성은 <meta name="google-signin-client_id"> 태그에 있습니다(위에 강조 표시된 client-ID 자리 표시자를 대체). 클라이언트 보안 비밀번호는 필요하지 않습니다.
    Google OAuth 2.0 클라이언트 ID가 성공적으로 생성되면 'OAuth 클라이언트' 창에 클라이언트 보안 비밀번호와 함께 표시됩니다.
     
  9. 기본 사용자 인증 정보 화면에서 OAuth 동의 화면을 클릭합니다. 이메일 주소와 제품 이름을 입력합니다(그 외의 필드는 모두 선택 사항입니다).
     

해당 섹션으로 돌아가기 자격 증명을 사용하는 샘플 애플리케이션 만들기

NGINX Plus의 기본 JWT 지원 기능을 살펴보려면 지금 30일 무료 평가판을 시작하거나 문의해 주세요.


공유

작성자 소개

관련 블로그 게시물

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
NGINX | 2023. 11. 30.

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric

이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
NGINX | 2023. 03. 23.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법

앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
NGINX | 2021. 09. 27.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션

개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX | 2021. 07. 06.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법

NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX | 2021. 06. 30.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리

NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
NGINX | 2015. 03. 25.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유

Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.