본문 바로가기
서버구축 (WEB,DB)

OAuth 2.0 액세스 토큰을 Nginx 또는 Nginx Plus로 검증

by 날으는물고기 2023. 10. 19.

OAuth 2.0 액세스 토큰을 Nginx 또는 Nginx Plus로 검증

Nginx를 사용하여 웹 사이트에 Google OTP(One-Time Password) 인증을 추가하는 것은 웹 액세스 보안을 강화하는 효과적인 방법 중 하나입니다.

How to setup an NGINX reverse proxy on Google Cloud

Google OTP 인증을 구현하려면 먼저 Python 및 PIP를 설치해야 합니다.

 

  1. Python 및 필수 라이브러리 설치
    서버에 Python을 설치하고, 필요한 라이브러리를 설치하세요.
    sudo apt-get update
    sudo apt-get install python3 python3-pip
    pip3 install flask pyotp
  2. Flask 애플리케이션 작성
    Google OTP 인증을 처리할 간단한 Flask 애플리케이션을 작성합니다.
    from flask import Flask, render_template, request, redirect, url_for
    from pyotp import TOTP
    
    app = Flask(__name__)
    
    # 임의의 시크릿 키 생성
    SECRET_KEY = "your_secret_key_here"
    # TOTP 인스턴스 생성
    totp = TOTP(SECRET_KEY)
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    @app.route('/verify', methods=['POST'])
    def verify():
        otp = request.form.get('otp')
        if totp.verify(otp):
            # OTP가 유효한 경우, 웹 사이트로 리디렉션
            return redirect(url_for('your_protected_page'))
        else:
            # OTP가 유효하지 않은 경우 에러 메시지 표시
            return "Invalid OTP"
    
    if __name__ == '__main__':
        app.run(debug=True)
    your_secret_key_here 부분을 실제로 사용할 고유한 시크릿 키로 바꾸세요.

  3. Flask 템플릿 생성
    templates 디렉토리에 index.html 템플릿 파일을 생성하고 OTP 입력 폼을 추가하세요.
    <!DOCTYPE html>
    <html>
    <head>
        <title>Google OTP Authentication</title>
    </head>
    <body>
        <h1>Enter OTP:</h1>
        <form method="POST" action="/verify">
            <input type="text" name="otp" placeholder="Enter OTP" required>
            <input type="submit" value="Verify">
        </form>
    </body>
    </html>
  4. Nginx 설정
    Nginx 구성 파일 (/etc/nginx/nginx.conf 또는 /etc/nginx/sites-available/default)을 열고 다음 구성 블록을 추가합니다.
    server {
        listen 80;
        server_name yourdomain.com;
    
        location / {
            proxy_pass http://127.0.0.1:5000; # Flask 애플리케이션으로 프록시
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    yourdomain.com은 실제 도메인 이름으로 바꿔주세요.

  5. Nginx 재시작
    Nginx를 재시작하여 변경 사항을 적용합니다.
    sudo service nginx restart
  6. Flask 애플리케이션 실행
    Flask 애플리케이션을 실행합니다.
    python3 your_flask_app.py

    이제 웹 사이트에 접근하려면 OTP를 입력해야 합니다. OTP가 올바르면 Flask 애플리케이션으로 리디렉션됩니다.

이제 Nginx를 통해 Google OTP 인증을 추가한 웹 사이트를 사용할 수 있습니다. 이 방법은 추가 보안 계층을 제공하며, 방문자가 유효한 OTP를 입력하지 않는 한 웹 사이트에 액세스할 수 없습니다.

 

OAuth 2.0 액세스 토큰을 Nginx 또는 Nginx Plus로 검증하려면 Nginx OAuth 2.0 플러그인을 사용하는 것이 가장 효과적입니다. 이 플러그인은 OAuth 2.0 인증을 쉽게 구현할 수 있도록 도와주며, OAuth 2.0 서버 (예: Auth0, Okta, Google OAuth 등)에서 발급한 토큰을 검증하여 액세스를 허용 또는 거부할 수 있습니다.

Authenticating Users with OpenID Connect and NGINX Plus

다음은 OAuth 2.0 액세스 토큰을 Nginx 및 Nginx Plus로 검증하는 단계입니다.

 

  1. Nginx Lua 모듈 설치
    Nginx OAuth 2.0 플러그인을 사용하려면 Nginx Lua 모듈을 설치해야 합니다. Lua 모듈을 사용하여 Lua 스크립트를 실행할 수 있습니다.
    sudo apt-get install nginx-extras
    또는
    sudo yum install nginx-plus-module-lua
  2. Nginx 설정 파일 수정
    Nginx 설정 파일 (일반적으로 /etc/nginx/nginx.conf 또는 /etc/nginx/sites-available/default)을 열고 다음과 같은 내용을 추가합니다.
    location /secure-resource {
        access_by_lua_block {
            local cjson = require "cjson"
            local introspect_url = "https://oauth2-provider.com/introspect"  -- OAuth 2.0 토큰 검증 엔드포인트
            local introspect_token = "your_client_secret"  -- 클라이언트 시크릿
    
            ngx.req.read_body()
    
            local args, err = ngx.req.get_post_args()
            if not args then
                ngx.status = 400
                ngx.say("Error parsing request body: ", err)
                return ngx.exit(ngx.HTTP_BAD_REQUEST)
            end
    
            local token = args.token
            if not token then
                ngx.status = 400
                ngx.say("Token missing in request body")
                return ngx.exit(ngx.HTTP_BAD_REQUEST)
            end
    
            local http = require "resty.http"
            local httpc = http.new()
            local res, err = httpc:request_uri(introspect_url, {
                method = "POST",
                body = "token=" .. token .. "&client_secret=" .. introspect_token,
                headers = {
                    ["Content-Type"] = "application/x-www-form-urlencoded",
                },
            })
    
            if not res then
                ngx.status = 500
                ngx.say("Error making HTTP request: ", err)
                return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
            end
    
            local introspect_response = cjson.decode(res.body)
            if introspect_response.active then
                -- 토큰이 유효하므로 요청 허용
            else
                ngx.status = 401
                ngx.say("Token invalid")
                return ngx.exit(ngx.HTTP_UNAUTHORIZED)
            end
        }
        proxy_pass http://backend-service;
    }
    위 설정에서 /secure-resource 경로는 OAuth 2.0 액세스 토큰을 검증하고 액세스를 제어하는 엔드포인트입니다. introspect_urlintrospect_token 값을 실제 OAuth 2.0 인증 서버 및 클라이언트 시크릿 값으로 대체해야 합니다.

  3. Nginx 재시작
    설정을 저장하고 Nginx를 재시작하여 변경 사항을 적용합니다.
    sudo service nginx restart
  4. 프록시 백엔드 구성
    /secure-resource 경로로 오는 요청을 처리할 프록시 백엔드 서비스를 설정하고 해당 서비스가 요청을 처리하도록 구성하세요.
    upstream backend-service {
        server 127.0.0.1:8080;  # 프록시 백엔드 서비스 주소
    }
  5. OAuth 2.0 토큰 가져오기
    클라이언트 애플리케이션에서 OAuth 2.0 토큰을 얻은 후, 요청 헤더 또는 본문에 해당 토큰을 포함하여 /secure-resource로 요청을 보내세요. Nginx는 Lua 스크립트를 통해 토큰을 검증하고 요청을 처리합니다.

이러한 설정은 OAuth 2.0를 통한 강력한 보안을 제공하며, 악의적인 요청으로부터 리소스를 보호합니다.

Using NGINX Plus and NGINX to Authenticate Users with Okta

NGINX Plus와 Okta를 사용한 OpenID Connect 통합 설정 단계별 가이드입니다. 이 설정은 NGINX Plus 구성을 통해 사용자를 Okta Identity Provider (IdP)로 리디렉션하고 인증을 처리하며, 필요한 설정 파일 및 세부 정보 수집 방법에 대한 설명을 포함합니다. 이 설정은 NGINX Plus 전용이므로 오픈 소스 NGINX에서는 작동하지 않습니다.

 

환경 설정 전 필요 사항:

  • Okta 계정이 생성되었으며 필요한 정보에 액세스할 수 있어야 합니다.
  • NGINX Plus 인스턴스가 실행 중이어야 합니다.
  • 백엔드 응용 프로그램 서버가 실행 중이어야 합니다.

 

1. Okta에서의 설정

1.1. Okta 포털에서 응용 프로그램 만들기

  • Okta 관리자 포털에 로그인하고 "Add App (Single Sign-on 사용)"을 클릭합니다.
  • "Application name"을 지정하고 "Login redirect URI"를 설정합니다. 이 URI는 NGINX Plus 인스턴스의 주소(포트 번호 포함)와 "/_codexch" 경로로 설정해야 합니다. 예: https://nginx-plus-instance.com:443/_codexch
  • "Client ID" 및 "Client Secret" 값을 복사하고 나중에 사용하기 위해 저장합니다.

1.2. OpenID Connect Discovery에서 필요한 정보 가져오기

  • 브라우저에서 다음 URL을 열어 OIDC Discovery 정보를 가져옵니다.
    https://nginxjdesai.okta.com/.well-known/openid-configuration
  • 가져온 정보 중에서 다음 값을 확인하고 나중에 NGINX Plus 구성에서 사용합니다.
    • "authorization_endpoint": Okta의 인증 엔드포인트 URL
    • "token_endpoint": Okta의 토큰 엔드포인트 URL
    • "jwks_uri": Okta의 JSON Web Key Set (JWKS) 엔드포인트 URL

 

2. NGINX Plus 구성

2.1. openid_connect_configuration.conf 파일 수정

  • 이 파일은 하나 이상의 IdP 구성에 대한 기본 설정을 가지고 있습니다. 필요한 설정을 수정하세요.
  • $oidc_authz_endpoint, $oidc_token_endpoint, $oidc_jwt_keyfile, $oidc_client, 및 $oidc_client_secret과 관련된 $oidc_ 블록을 설정값에 맞게 수정합니다.
  • 본 레포지토리에 포함된 openid_connect_configuration.conf 파일은 이미 캡처된 값을 가지고 있으므로 참고로 사용할 수 있습니다.

2.2. frontend.conf 파일 수정

  • frontend.conf 파일을 수정합니다.
  • auth_jwt_key_file 지시문 주석 처리(또는 제거)합니다.
  • auth_jwt_key_request 지시문 주석 처리를 해제합니다.
    (파라미터 /_jwks_uri는 이전 단계에서 설정한 $oidc_jwt_keyfile 변수의 값과 관련이 있습니다.)

 

3. 마지막 확인 및 완료 단계

3.1. /etc/nginx/conf.d 디렉토리의 쓰기 권한 설정

  • 토큰을 저장할 수 있도록 /etc/nginx/conf.d 디렉토리에 필요한 권한을 부여합니다.

3.2. NGINX 리로드

  • NGINX 구성을 다시 불러오려면 다음 명령어를 실행합니다.
    sudo nginx -t
    sudo nginx -s reload

 

4. 문제 해결

  • OpenID Connect 흐름에서 생성된 오류는 /var/log/nginx/error.log 파일에 기록됩니다. 이 파일의 내용을 확인하여 Okta에서 받은 오류 응답을 확인합니다. 필요에 따라 error_log 지시문의 심각도 수준을 조정하여 기록 세부 정보를 수정할 수 있습니다.

 

이제 NGINX Plus와 Okta를 통합한 OpenID Connect 인증 설정이 완료되었습니다.

728x90

댓글