$30 off During Our Annual Pro Sale. View Details »

Introduction of AuthN/AuthZ behind “GOOD DESIGN...

Introduction of AuthN/AuthZ behind “GOOD DESIGN AWARD” stories

Spring Fest 2023 にて登壇した内容になります
https://springfest2023.springframework.jp/
本資料は Miro で作成しており下記 URL から閲覧することができます
https://miro.com/app/board/uXjVMc_RaIc=/

Jun Koyama

March 19, 2023
Tweet

Other Decks in Programming

Transcript

  1. Jun Koyama Tagbangers, Inc. We Make Stories. 社会人4 年目 /

    TB 3 年目 About speaker Spring / React / AWS / DevOps 日々の仕事をクリエイティブにする ソフトウェアを作っています 技術ブログ 初登壇 💪 デジタルプロダクト構築・成長支援 Spring 設計・開発支援 Architecture モダナイゼーション
  2. 1 / 6 Introduction About this Session Tagbangers で実際に携わっている業務アプリケーションの 認証認可にフォーカスした活用実績の紹介

    OpenID Connect OAuth 2.0 Keycloak Spring Security Spring Cloud Gateway プロダクトとアーキテクチャの紹介 二種類の認証認可の事例に関してご紹介 ユーザ端末からのブラウザ利用時 信頼できる端末の Native アプリ利用時
  3. Introduction Tagbangers では 公益財団法人日本デザイン振興会 の 「グッドデザイン賞」システムの開発・運用を行っています www.g-mark.org GOOD DESIGN AWARD

    グッドデザイン賞の仕組みや、過去のす べての受賞対象が検索できる「グッドデ ザインファインダー」など、グッドデザ イン賞に関する情報をご紹介するサイト です。毎年1 回(4 ~6 月頃)募集する、グ ッドデザイン賞への応募もこのサイトか ら行うことができます。 1 / 6
  4. Introduction 応募 審査 受賞発表 グッドデザイン賞システム 応募者 審査委員 様々な利用者 応募 アプリケーション

    応募 審査 アプリケーション 審査 受賞ギャラリー アプリケーション 回覧 ...etc 2 / 6 ...and more グッドデザイン賞システムにはさまざまなコンテキストとアプリケーションが稼働
  5. Introduction 応募 審査 受賞発表 グッドデザイン賞システム 応募者 審査委員 様々な利用者 応募 アプリケーション

    応募 審査 アプリケーション 審査 受賞ギャラリー アプリケーション 回覧 ...etc 認証認可にフォーカスした話 3 / 6
  6. グッドデザイン賞システム 審査アプリ Introduction API Gateway 審査 API Browser 審査フロント (SPA)

    応募画像 API 応募アプリ (SSR) メンテナンス (Static Web ) ...etc アプリをさまざまな単位で稼働 API Gateway サーバが リクエストを集約 4 / 6
  7. Introduction API Gateway 審査 API Browser 応募画像 API 応募アプリ (SSR)

    1 つ1 つのアプリに対して 認証認可の実装を行っていくのは コストが高い... 応募権限のある ユーザのみ許可 審査権限のある ユーザのみ許可 閲覧権限のある ユーザのみ許可 いくつかのリソースは保護されている 5 / 6
  8. Introduction OpenID Connect による認証認可の分離を行うアプローチ API Gateway Browser Resource Servers Keycloak

    AuthZ Server OAuth Client 審査 API 応募画像 API 応募アプリ (SSR) 認可 トークン 管理 認証 6 / 6
  9. User device About browser AuthN/AuthZ flow 1 / 12 応募情報を閲覧・メモ・審査・評価...etc

    審査 アプリ 審査委員 Browser https://youtu.be/CIQgX0D-​ 930 通常審査 審査情報 + 応募画像 +α... 通常は手持ちの端末からアクセス 審査アプリケーション
  10. API Gateway Browser ① Request resource ① ブラウザから API Gateway

    に対してフロントエンドページをリクエスト ② API Gateway がフロントエンドアプリ対してリクエストを渡す  → 認証はかかっていないのでフロントエンドのリソースが取得できる https://api-​ gateway/judge/ ブラウザでは初回ページが表示されている状態 審査フロント (SPA) ② Request Resource About browser AuthN/AuthZ flow 3 / 12 1. 審査アプリのフロントエンドリソースを取得
  11. API Gateway 審査 API Resource Servers OAuth Client Browser ①

    Request resource ② Request resource ❌ Rejected ① ブラウザから API Gateway に対して API を Ajax リクエスト ② API Gateway が保護された API に対してリクエストを渡す 401 Unauthorized Loading resources... https://api-​ gateway/api/judge/entries ブラウザではデータロード中の表示状態 About browser AuthN/AuthZ flow 4 / 12 2. 審査アプリで利用する保護されたリソースをリクエスト 未認証のリクエストのため API は 401 エラーをレスポンスする
  12. API Gateway Keycloak AuthZ Server OAuth Client Browser ① Require

    AuthZ ② Redirect to Login page ① ブラウザは API Gateway に対し認証をリクエスト ② 認証サーバの認証ページにリダイレクト、 https://api-​ gateway/oauth2/authorization/judge?... https://keycloak/auth/realms/judge/protocol/openid-​ connect/auth?... ID & Password + MFA の二段階認証 ③ API Gateway にリダイレクト https://api-​ gateway/login/oauth2/code/judge?... Judge Realm user-​ a user-​ b ... client: gmark-​ api scope: judge:judge ユーザやクライアントなどの 認証・認可のリソースを管理 ③ Issue token API Gateway はトークンを認証サーバにリクエストし 取得したトークンをセッションに保存 About browser AuthN/AuthZ flow 5 / 12 3. 審査アプリは認証をリクエスト Authorization Code Flow
  13. ③ Issue token API Gateway Keycloak AuthZ Server OAuth Client

    Browser ① Require AuthZ ② Redirect to Login page spring-​ boot-​ starter-​ oauth2-​ client @Configuration public class SecurityConfig { @Bean SecurityWebFilterChain springSecurityFilterChain (ServerHttpSecurity http) { return http.oauth2Login(oauth2 -> ...).build(); } } spring: security: oauth2: client: registration: judge: client-id: "gmark-​ api" client-secret: "..." scope: "judge:judge" redirect-uri: "​ {baseUrl}/login/oauth2/code/{registrationId}" provider: judge: issuer-uri: "https://keycloak/auth/realms/judge" SecurityConfig application.yml 認証成功後のリダイレクト先 認可に使う予定のスコープ 認証サーバのクライアント ID 認証成功後のリダイレクト先 トークン取得先などの情報が含まれるURL About browser AuthN/AuthZ flow 6 / 12
  14. API Gateway Keycloak 審査 API Resource Servers AuthZ Server OAuth

    Client Browser ① Request resource ② Request with token ✅ Accept Request ③ Validate token ① ブラウザは API Gateway に対して API を Ajax リクエスト ② API Gateway がセッションからトークンを取り出し  保護された API サーバのリクエストに添付する ③ 保護された API サーバはトークンの権限と有効性を検証  問題なければ保護されたリソースをレスポンスする About browser AuthN/AuthZ 7 / 12 4. 審査アプリで利用する保護されたリソースをリクエスト https://api-​ gateway/api/judge/entries API Gateway には TokenRelay を有効にする必要あり spring: cloud: gateway: default-filters: - TokenRelay= Spring Cloud Gateway を利用している場合 application.yml に記述
  15. API Gateway Keycloak 審査 API Resource Servers AuthZ Server OAuth

    Client Browser ① Request resource ② Request with token ✅ Accept Request ③ Validate token spring-​ boot-​ starter-​ oauth2-​ resource-​ server @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .authorizeRequests(authz -> authz .anyRequest().hasAnyAuthority("SCOPE_judge:judge")) .oauth2ResourceServer(oauth2 -> ...) .build(); } } SecurityConfig { ... "scope": "judge:judge ...", ... } jwt.io JWT.IO JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiS... decode Payload 権限が含まれているか検証 権限がない場合は 403 Forbidden エラーを返す About browser AuthN/AuthZ 8 / 12
  16. spring: security: oauth2: resourceserver: jwt: jwk-set-uri: "https://keycloak/auth/realms/judge/protocol/openid-​ connect/certs" API Gateway

    Keycloak 審査 API Resource Servers AuthZ Server OAuth Client Browser ① Request resource ② Request with token ✅ Accept Request ③ Validate token spring-​ boot-​ starter-​ oauth2-​ resource-​ server jwt.io JWT.IO JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiS... VERIFY SIGNATURE decode ... 署名の有効性を検証 署名の検証により不正なトークンに よるリクエストを拒否 application.yml About browser AuthN/AuthZ 9 / 12
  17. API Gateway Keycloak 審査 API Resource Servers AuthZ Server OAuth

    Client Browser ① Request resource ② Request with token ✅ Accept Request ③ Validate token About browser AuthN/AuthZ 10 / 12 以降はトークンを用いて保護されたリソースにアクセス JWT トークンはブラウザに公開されない
  18. API Gateway Keycloak 審査 API Resource Servers AuthZ Server OAuth

    Client Browser ① Request resource Issue token ③ Request with token ④ Validate token About browser AuthN/AuthZ トークンには期限がある → OAuth Client がトークンの更新管理を行う Spring は TokenRelay が有効であれば 自動でトークンを更新管理 リフレッシュトークンがあればアクセストークンを再取得 アクセストークンは一般的には短い時間で期限が設定されている 必要なセットアップを終えれば 手軽に認証認可を運用可能 11 / 12 Expired Token...
  19. About browser AuthN/AuthZ API Gateway Browser Resource Servers Keycloak AuthZ

    Server OAuth Client 審査 API 応募画像 API 応募アプリ (SSR) 一度のログインで複数の保護リソースにアクセス可能 = Single Sign On 応募権限 閲覧権限 審査権限 12 / 12 審査情報 + 応募画像 +α... ❌403 ✅200 ✅200 閲覧権限 審査権限
  20. Loginless AuthN for trusted device https://youtu.be/CIQgX0D-​ 930 Trusted device 審査

    アプリ 審査委員 Browser スムーズに応募情報にアクセスできるよう 自動認証された審査アプリを利用 審査委員ごとに個別の端末が配布 ログイン画面を 出さない 2 / 7
  21. Loginless AuthN for trusted device Trusted device 審査 アプリ 審査委員

    Native App WebView を用いた Native アプリを用意 WebView AuthZ Info 3 / 7 OAuth Client Native App WebView AuthZ Info Keycloak AuthZ Server Issue token Inject token Native アプリを OAuth Client として トークンの発行・管理を行わせる Native アプリから WebView に トークンを注入しリクエストに付与する
  22. 4 / 7 window.accessToken = "<ACCESS_TOKEN>" Loginless AuthN for trusted

    device 審査 API Resource Server API Gateway ④ Request with token OAuth Client Native App WebView AuthZ Info ③ Request with token Keycloak AuthZ Server ① Issue token ✅ Accept Request ① アプリは認証サーバに対してトークンの発行をリクエスト ② 取得したトークンを WebView に変数として渡す ③ WebView の Ajax リクエストに対して Bearer Token を付与 認可のフロー https://keycloak/auth/realms/judge/protocol/openid-​ connect/token?... ⑤ Validate token ④ API Gateway が保護された API に対してリクエストを渡す const open = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { open.apply(this, arguments); this.setRequestHeader("Authorization", `Bearer ${window.accessToken}`); }; ② Inject token ⑤ 有効なトークンが付与されているため API は保護されたリソースをレスポンスする
  23. 5 / 7 Loginless AuthN for trusted device 応募画像 API

    Resource Server API Gateway OAuth Client Native App WebView AuthZ Info @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { var bearerTokenResolver = new DefaultBearerTokenResolver(); bearerTokenResolver.setAllowUriQueryParameter(true); return http ... .oauth2ResourceServer().bearerTokenResolver(bearerTokenResolver) ... } トークンのパラメータ受け渡し許可を設定 保護された画像を img タグで利用する場合 <img src={`https://.../image.jpeg?access_token=${window.accessToken}`} /> img タグに Header を設定できないのでパラメータにトークンをセット
  24. 6 / 7 OAuth 2.0 Token Exchange ある Token から別の

    Token に変換する (外部アカウントトークンから内部アカウントトークンなど) RFC 8693 Loginless AuthN for trusted device Token Exchange を用いて認証サーバの Client からユーザの Token を取得 Keycloak AuthZ Server OAuth Client Native App WebView AuthZ Info Token Exchange Token Exchange Flow
  25. 7 / 7 Loginless AuthN for trusted device 審査 API

    Resource Server API Gateway ③ Request with token OAuth Client Native App WebView AuthZ Info ② Request with token Keycloak AuthZ Server ① Issue token ✅ Accept Request ④ Validate token 以降はトークンを用いて保護されたリソースにアクセス Trusted device 自動的に認証された状態で審査アプリが利用できるように
  26. Ending API Gateway Keycloak 審査 API Resource Servers AuthZ Server

    OAuth Client Browser 審査 API API Gateway OAuth Client Native App WebView AuthZ Info Keycloak AuthZ Server Authorization Code Flow ユーザ端末からのブラウザ利用時 Token Exchange Flow 信頼できる端末の Native アプリ利用時 Resource Server グッドデザイン賞システムは OpenID Connect による認証認可の分離を行なっており 審査アプリではユースケースに応じた2 種類のフローを実装
  27. Ending API Gateway Keycloak 審査 API Resource Servers AuthZ Server

    OAuth Client Browser 審査 API API Gateway OAuth Client Native App WebView AuthZ Info Keycloak AuthZ Server Authorization Code Flow ユーザ端末からのブラウザ利用時 Token Exchange Flow 信頼できる端末の Native アプリ利用時 Resource Server 認証の違いのみで保護リソースアプリの認証は同じ 柔軟な認証認可の運用を実現