JWT Token 기반 인증 인가


마이크로서비스와 OAuth2 구성요소인 Authorization Server/ Client/ Resource Server를 활용해 Single Sign-On 구현 모형을 실습합니다.

단일 접점인 Gateway가 Client가 되고, 각 마이크로서비스가 Resource Server에 해당됩니다. 그리고 Authorization Server로는 Keycloak을 활용합니다.

본 랩에서는 Gateway가 Client와 Resource Server역할을 가집니다.

JWT기반 인증 w/ Keycloak

  • OAuth2.0 기반의 Spring Security와 Resource Owner, Client, Authorization Server, Resource Server간의 인증/인가를 실습합니다.
  • JWT기반 Access_Token을 활용합니다.
  • 인증/인가 서버로 Keycloak 서버를 활용합니다.

이벤트스토밍 모델 준비

  • 아래 모델을 새 탭에서 로딩합니다. 모델 링크
  • 브라우져에 모델이 로딩되지 않으면, 우측 상단의 (사람모양) 아바타 아이콘을 클릭하여 깃헙(Github) 계정으로 로그인 후 리로드하면 아래처럼 랩에 필요한 이벤트스토밍 기본 모델이 출력됩니다.
  • 로딩된 모델은 우측 팔레트 영역에 스티커 목록이 나타나지 않습니다. 상단 메뉴영역에서 포크 아이콘(FORK)을 클릭해 주어진 모델을 복제합니다.

image

  • 우측 팔레트 영역에 스티커 목록들이 나타나는 것이 확인됩니다.

Keycloak 토핑설정 및 코드 Push

  • 우측 상단의 CODE 버튼을 눌러 TOPPINGS를 클릭합니다.
  • Oauth by Keycloak이 체크되어 있어야 합니다.
  • 상단의 Push to Git 메뉴를 클릭해 나타나는 다이얼로그 박스에서 Create New Repository를 선택하고, CREATE를 누릅니다.

    초기 Github 계정으로 로그인 하였으므로, 나의 Git 정보가 자동으로 표시됩니다.

image

  • 모델 기반 코드가 내 Github에 Push됩니다.

image

  • 좌측 메뉴 IDE를 누른 다음, Cloud IDE 목록에서 Open GitPod를 클릭합니다.

Keycloak Server 실행

  • Cloud IDE 터미널에서 keycloak 폴더로 이동하여 컨테이너를 생성하고 및 Keycloak 서버를 실행합니다.
cd keycloak
docker-compose up -d
  • Keycloak이 사용하는 9090 포트가 목록에 나타납니다.

Keycloak 서버 오픈 및 접속하기

  • 오른쪽 하단의 포트 목록을 눌러 keycloak이 사용하는 9090 포트를 Public으로 오픈합니다. (두번째 자물쇠)

image

  • 첫 번째 아이콘을 클릭하여, KeyCloak의 풀 URL을 클립보드에 복사합니다.
  • Keycloak 마지막 브라우저 아이콘을 눌러, 웹 브라우저에서 접속합니다.
  • Administration Console을 클릭해 설정된 관리자 정보(admin / admin)로 로그인합니다.

image

  • Keycloak 메인 화면이 아래와 같이 출력됩니다.

image

OAuth Client 설정

Keycloak 설정

  • Master Realm에서 Tokens 탭을 눌러 Access Token Lifespan을 1시간으로 수정합니다.
  • 수정 후, 하단의 Save 를 눌러 저장합니다.

OAuth Client 설정

  • Keycloak 서버의 왼쪽메뉴에서 Clients를 눌러 12stmall 을 추가합니다.

image

  • 등록된 Client 설정에서 Access Type을 confidential로 설정합니다.

image

  • 아래에 있는 Valid Redirect URIs 설정에 다음과 같이 입력합니다.
  • 규칙 : Gateway Endpoint URL + /login/oauth2/code/ + ClientId(12stmall)
  • 오른쪽 하단의 포트목록을 눌러 keycloak이 사용하는 9090 포트의 첫번째 URL 복사 아이콘을 클릭합니다.
  • GitPod에서는 이처럼 포트로 시작하는 도메인 정보로 노출됩니다. 이 9090을 게이트웨이 포트인 8088로 변경합니다.

image

  • Valid Redirect URIs 정보는 이후 Gateway에도 추가합니다.
  • 저장 후, Credentials 탭을 확인하면 Secret(비밀번호)이 확인되는데 이는 이후 Gateway에도 추가합니다.

image

Gateway Client 설정

  • Keycloak Client설정에 필요한 아래 템플릿 환경정보를 설정합니다.
  • Gateway > applicaion.yml 8라인에 KeyCloak SSO 서버의 엔드포인트를 설정합니다.
keycloak-client:
  server-url: https://9090-acmexii-labshopoauthkey-sgn5ady40al.ws-us94.gitpod.io
  realm: master

server-url 값의 맨뒤에 / 가 없도록 주의합니다.

  • Spring OAuth2 Security 설정을 마무리합니다.
  security:
    oauth2:
      client:
        provider:
          keycloak:
            issuer-uri: ${keycloak-client.server-url}/realms/${keycloak-client.realm}
            user-name-attribute: preferred_username
        registration:
          keycloak:
            client-id: **<client-id>**
            client-secret: 
            redirect-uri: **gateway-path/login/oauth2/code/client-name**
            authorization-grant-type: authorization_code
            scope: openid
      resourceserver:
        jwt:
          jwk-set-uri: ${keycloak-client.server-url}/realms/${keycloak-client.realm}/protocol/openid-connect/certs

51라인에 OAuth Client value인 12stmall 입력

52라인에 KeyCloakd에 생성된 client-secret 입력

53라인에 KeyCloakd에 설정한 redirect-uri 입력

Test User 생성

  • Keycloak 서버의 왼쪽 메뉴에서 Manage > Users를 눌러 사용자를 등록합니다.

image

  • user@naver.com 으로 저장합니다.
  • 등록한 사용자의 Credentials 탭에서 비밀번호를 설정하고, Temporary를 OFF로 한 다음 설정합니다.

image

  • 동일한 방식으로 admin@naver.com도 생성해둡니다.

Keycloak SSO Test

  • Gateway와 마이크로서비스를 재시작합니다.
cd gateway
mvn clean spring-boot:run
  • 실행된 Gateway 서비스도 외부에서 접속이 가능하도록 GitPod에서 8088 Port를 오픈합니다.

image

  • 마이크로서비스를 시작합니다.
cd order
mvn clean spring-boot:run
  • 다음의 오류 발생시, 새 터미널에서 kafka를 시작합니다.
Broker may not be available.
2022-09-19 06:43:53.548  WARN [monolith,,,] 5204 --- [| adminclient-2] org.apache.kafka.clients.NetworkClient   : [AdminClient clientId=adminclient-2] Connection to node -1 (localhost/127.0.0.1:9092) could not be established. Broker may not be available.
cd kafka
docker-compose up -d

Token based Authentication 테스트

  • 크롬의 Secret 창 또는 다른 브라우저(Edge, 네이버웨일)에서 Gateway를 경유하는 Order서비스에 접속해 봅니다.
https://8088-acmexii-labshopmonolith-orw1glcgvae.ws-us65.gitpod.io/orders
(Gateway URL need to be modified)
  • 비인가된 Resource 접근으로 Keycloak SSO 로그인 창이 나타납니다.

    image

  • 관리콘솔에서 등록한 사용자(user@naver.com / 1)로 인증합니다.
  • 인증 성공 후, 주문서비스의 응답이 정상적으로 출력됩니다.

Token based Authorization 테스트

  • 특정 API를 권한을 가진 사용자만 접근할 수 있도록 권한(CUSTOMER, ADMIN)을 생성합니다.

image

  • 생성된 사용자에 각각 Role을 매핑합니다.
  • User > admin@naver.com를 선택하고, Role Mappings를 클릭합니다.

image

  • Realm Roles에 있는 ADMIN 권한을 Assign 합니다.
  • 마찬가지 방법으로 user@naver.com 사용자에게 CUSTOMER 권한을 Assign 합니다.

Order Resouces 권한 확인

  • 브라우저에서 주문 리소스에 user@naver.com 사용자로 접속해 봅니다.
https://8088-acmexii-labshopmonolith-orw1glcgvae.ws-us65.gitpod.io/orders/placeOrder
  • 이어서, 주문관리 리소스에 접속해 봅니다.
https://8088-acmexii-labshopmonolith-orw1glcgvae.ws-us65.gitpod.io/orders/manageOrder

user@naver.com의 권한으로는 접근이 불가능하여 정제되지 않은 403 오류가 리턴됩니다.

image

사용자 JWT Token 확인

  • 다음 URL로 접속하여 사용자 토큰 정보를 확인하고 전체 토큰값을 복사합니다. (아래 URL에서 내 Gateway 정보로 수정합니다.)
https://8088-acmexii-labshopmonolith-orw1glcgvae.ws-us65.gitpod.io/test/token
  • https://jwt.io/ 에 접속후 나타나는 Encoded Token에 복사한 토큰을 붙여넣습니다.

image

  • Decoded Token의 Payload에서 User Claim의 Role확인이 가능하다.
uEngine has registered trademarks and uses trademarks. and MSA-Ez is licensed under the GNU General Public License version 3.0.