Skip to content

spring-boot-study-project/Spring-Security-oauth2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

28 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Spring-Security-oauth2

์ปค๋ฐ‹ ๊ทœ์น™

init ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
feat ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ปค๋ฐ‹
build ๋นŒ๋“œ ๊ด€๋ จ ํŒŒ์ผ ์ˆ˜์ • / ๋ชจ๋“ˆ ์„ค์น˜ ๋˜๋Š” ์‚ญ์ œ์— ๋Œ€ํ•œ ์ปค๋ฐ‹
chore ๊ทธ ์™ธ ์ž์ž˜ํ•œ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
docs ๋ฌธ์„œ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
style ์ฝ”๋“œ ์Šคํƒ€์ผ ํ˜น์€ ํฌ๋งท ๋“ฑ์— ๊ด€ํ•œ ์ปค๋ฐ‹
refactor ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง์— ๋Œ€ํ•œ ์ปค๋ฐ‹
test ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปค๋ฐ‹
perf ์„ฑ๋Šฅ ๊ฐœ์„ ์— ๋Œ€ํ•œ ์ปค๋ฐ‹

OAuth2.0์˜ ๊ธฐ๋ณธ ์›๋ฆฌ๋ž€?

  • OAuth = Open + Authorization ๊ธฐ๋ณธ ์›๋ฆฌ๋Š” ์œ ์ €๊ฐ€ ์Šน์ธํ•˜์— ๋‹ค๋ฅธ ์„œ๋ฒ„์— ์œ ์ €์˜ ์ •๋ณด๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ -> ์ด๋Ÿฌํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด ์ธ๊ฐ€ ์„œ๋ฒ„๋ผ๊ณ  ํ•จ.

OAuth2.0 Roles

  • OAuth2.0 ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋‹ค์Œ 4๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ๊ถŒํ•œ ๋ถ€์—ฌ ์ฒด๊ณ„์ด๋‹ค.
  1. Resource Owner
  • ๋ณดํ˜ธ๋œ ์ž์›์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์ฒด
  • ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•ด์„œ ์ž‘๋™ํ•˜๋ ค๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๋Š” ์‚ฌ์šฉ์ž์˜ ํ—ˆ๊ฐ€๋ถ€ํ„ฐ ๋ฐ›์•„์•ผ ๋œ๋‹ค.
  1. Resource Server
  • ํƒ€์‚ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ ‘๊ทผํ•˜๋Š” ์‚ฌ์šฉ์ž์˜ ์ž์›์ด ํฌํ•จ๋œ ์„œ๋ฒ„๋ฅผ ์˜๋ฏธ
  • ์•ก์„ธ์Šค ํ† ํฐ์„ ์ˆ˜๋ฝ ๋ฐ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ๊ถŒํ•œ ์ฒด๊ณ„์— ๋”ฐ๋ผ ์š”์ฒญ ์Šน์ธํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  1. Authorization Server
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‚ฌ์šฉ์ž ๊ณ„์ •์— ๋Œ€ํ•œ ๋™์˜ ๋ฐ ์ ‘๊ทผ์„ ์š”์ฒญํ•  ๋•Œ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์„œ๋ฒ„๋กœ ํด๋ผ์ด์–ธํŠธ์˜ ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์„ ์Šน์ธํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€ํ•˜๋Š” ์„œ๋ฒ„
  • ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์„ ์Šน์ธํ•œ ํ›„ accessToken์„ ํด๋ผ์—๊ฒŒ ๋ถ€์—ฌํ•˜๋Š” ์—ญํ• 
  1. Client
  • ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•ด์„œ ๊ถŒํ•œ์„ ๋ฐ›์•„ ์‚ฌ์šฉ์ž์˜ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๋ ค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
  • ์‚ฌ์šฉ์ž๋ฅผ ๊ถŒํ•œ ๋ถ€์—ฌ ์„œ๋ฒ„๋กœ ์•ˆ๋‚ดํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž์˜ ์ƒํ˜ธ์ž‘์šฉ ์—†์ด ๊ถŒํ•œ ๋ถ€์—ฌ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ง์ ‘ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ณดํ†ต Client๋งŒ ์‚ฌ์šฉํ•ด์„œ ๋‹ค๋ฅธ ์ธ๊ฐ€ ์„œ๋ฒ„์ธ ๊ตฌ๊ธ€, ๋„ค์ด๋ฒ„, ์นด์นด์˜ค์— ์ธ๊ฐ€ ์š”์ฒญ์„ ํ•˜๊ฒŒ ๋˜๊ณ  ์ดํ›„ ํ† ํฐ์„ ๊ฐ€์ง€๊ณ  ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.

OAuth2.0์˜ ์˜คํ•ด

OAuth2.0์€ ์ธ๊ฐ€์™€ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ฆํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ์•Œ๊ธฐ ์‰ฌ์šด๋ฐ OAuth2.0์€ ์ธ๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

OAuth2.0 ๊ถŒํ•œ ๋ถ€์—ฌ ์œ ํ˜•

  1. Authorization Code Grant Type : ๊ถŒํ•œ ์ฝ”๋“œ ๋ถ€์—ฌ ํƒ€์ž…, ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜, ๋ณด์•ˆ์— ๊ฐ€์žฅ ์•ˆ์ „ํ•œ ์œ ํ˜•
  • 1๋‹จ๊ณ„ : ์ธ๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ code๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
  • 2๋‹จ๊ณ„ : code๋ฅผ ํ†ตํ•ด์„œ accessToken, refreshToken์„ ๋ฐ›์•„์˜จ๋‹ค. => ์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์ธ๊ฐ€ ๋‹จ๊ณ„
  • 3๋‹จ๊ณ„ : accessToken์„ ํ†ตํ•ด์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜จ๋‹ค. => ์—ฌ๊ธฐ๋ถ€ํ„ฐ ์ธ์ฆ ๋‹จ๊ณ„
  1. Client Credentials Grant Type : ํด๋ผ์ด์–ธํŠธ ์ž๊ฒฉ ์ฆ๋ช… ๊ถŒํ•œ ๋ถ€์—ฌ ํƒ€์ž…, ํ™”๋ฉด์ด ์—†๋Š” ์„œ๋ฒ„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜
  • 1๋‹จ๊ณ„ : ์ธ๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ code๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
  • 2๋‹จ๊ณ„ : code๋ฅผ ํ†ตํ•ด์„œ accessToken, refreshToken์„ ๋ฐ›์•„์˜จ๋‹ค. => ์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์ธ๊ฐ€ ๋‹จ๊ณ„

โ‡’ ์„œ๋ฒ„๋ผ๋ฆฌ์˜ ํ†ต์‹ ๊ณผ์ •์—์„œ ํ•„์š”ํ•œ ํƒ€์ž… ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋Š” ํ•„์š” ์—†๋‹ค -> ์‚ฌ์šฉ์ž ์ธ์ฆ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๊ฐœ๋…์ด ์—†์Œ

  1. Refresh Token Grant Type : ์ƒˆ๋กœ๊ณ ์นจ ํ† ํฐ ๋ถ€์—ฌ ํƒ€์ž…, Authorization Code, Resource Owner Password Type์—์„œ ์ง€์›

  2. PKCE-enhanced Authorization Code Grant Type : PKCE ๊ถŒํ•œ ์ฝ”๋“œ ๋ถ€์—ฌ ํƒ€์ž…, ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜, ๊ณต๊ฐœ ํด๋ผ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜

โ‡’ 1๋‹จ๊ณ„์—์„œ ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋” ์กด์žฌํ•œ๋‹ค. code(๊ธฐ์กด์˜ ์ฝ”๋“œ์™€๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ์ž„) โ‡’ 2๋‹จ๊ณ„์—์„œ ์ฝ”๋“œ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ „๋‹ฌํ•œ๋‹ค. 2๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋” ํ•„์š”(์ธ๊ฐ€ ์„œ๋ฒ„์™€ ๋น„๊ต๋ฅผ ํ†ตํ•ด์„œ ๋™์ผํ•œ ํด๋ผ์ด์–ธํŠธ์ผ ๊ฒฝ์šฐ์—๋งŒ ํ—ˆ์šฉ) ์—ฌ๊ธฐ์„œ 1๋‹จ๊ณ„์˜ ์ฒ˜๋ฆฌ ๊ณผ์ •์ด ๋” ๋Š˜์–ด๋‚œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

OpenID connect 1.0

OpenID Connect 1.0์€ OAuth 2.0 ํ”„๋กœํ† ์ฝœ ์œ„์— ๊ตฌ์ถ•๋œ ID ๊ณ„์ธต์œผ๋กœ OAuth2.0์„ ํ™•์žฅํ•˜์—ฌ ์ธ์ฆ ๋ฐฉ์‹์„ ํ‘œ์ค€ํ™”ํ•œ OAuth2.0 ๊ธฐ๋ฐ˜์˜ ์ธ์ฆ ํ”„๋กœํ† ์ฝœ์ด๋‹ค.

  • scope ์ง€์ • ์‹œ openid๋ฅผ ํฌํ•จํ•˜๋ฉด OpenID Connect ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ธ์ฆ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ID ํ† ํฐ์ด๋ผ๋Š” JSON ์›น ํ† ํฐ์œผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • OpenID Connect๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‚ฌ์šฉ์ž ID๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ณด์•ˆ ํ† ํฐ์ธ ID Token์„ ์ œ๊ณตํ•œ๋‹ค.

์ธ์ฆ์„ ์œ„ํ•œ ํ”„๋กœํ† ์ฝœ์ด๋‹ค. ์Šค์ฝ”ํ”„์— openid๊ฐ€ ํฌํ•จ๋˜๋ฉด ์ธ๊ฐ€์„œ๋ฒ„์—์„œ openid connect๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

OpenID Connect๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ์—”๋“œ ํฌ์ธํŠธ ๋ฐ ๊ณต๊ฐœ ํ‚ค ์œ„์น˜ ์ •๋ณด๋ฅผ ํฌํ•จ ํ•˜์—ฌ OpenId ๊ณต๊ธ‰์ž์˜ ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ํด๋ ˆ์ž„ ์ง‘ํ•ฉ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ธ๊ฐ€ ์„œ๋ฒ„

์ธ๊ฐ€ ์„œ๋ฒ„์˜ ์—ญํ• ์„ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค๊ฐ€ ์žˆ๋Š”๋ฐ KeyCloak์ด๋ผ๋Š” ๊ฑธ ๊ฐ€์ง€๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

  • ์„ค์น˜ ๋ฐฉ๋ฒ• dockerHub์— bitnami์—์„œ ์ œ์ž‘ํ•œ keyCloak๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ ๊ณต์‹์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

์„ค์น˜ ์‚ฌ์ง„

version: '3.8'

services:
  postgresql:
    image: docker.io/bitnami/postgresql:latest
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - POSTGRESQL_USERNAME=bn_keycloak
      - POSTGRESQL_DATABASE=bitnami_keycloak
    volumes:
      - 'postgresql_data:/bitnami/postgresql'

  keycloak:
    image: docker.io/bitnami/keycloak:latest
    ports:
      - "80:8080"
    environment:
      - KEYCLOAK_CREATE_ADMIN_USER=true
      - KEYCLOAK_ADMIN_USER=admin
      - KEYCLOAK_ADMIN_PASSWORD=admin
      - KEYCLOAK_DATABASE_HOST=postgresql
      - KEYCLOAK_DATABASE_NAME=bitnami_keycloak
      - KEYCLOAK_DATABASE_USER=bn_keycloak
      - KEYCLOAK_DATABASE_PASSWORD=
    depends_on:
      - postgresql
    volumes:
      - './mynewtheme:/opt/bitnami/keycloak/themes/mynewtheme'

volumes:
  postgresql_data:
    driver: local

์ด์ฒ˜๋Ÿผ ์ธ๊ฐ€์„œ๋ฒ„๋ฅผ ๊ฐ€์ง€๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ณ  ๋กœ๊ทธ์ธ์„ ์ง„ํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

OAuth2.0 ์ดˆ๊ธฐ ์„ค์ • ๊ณผ์ •

security์—์„œ oauth2๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” yml ํŒŒ์ผ์— ํ•„์š”ํ•œ ์ •๋ณด๋“ค์„ ๊ธฐ์ž…ํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?

OAuth2ClientProperties ์„ค์ • ์‚ฌ์ง„ ์ด ํด๋ž˜์Šค์— ์ž์„ธํ•˜๊ฒŒ ๋‚˜์™€์žˆ๋‹ค ์—ฌ๊ธฐ๋ฅผ ์‚ดํŽด๋ณด๋ฉด prefix๋กœ spring.security.oauth2.client ์ด ๊ฐ’์„ ์ฃผ๊ณ  ๊ฐ’ ์…‹ํŒ…์€

private String provider;

		/**
		 * Client ID for the registration.
		 */
		private String clientId;

		/**
		 * Client secret of the registration.
		 */
		private String clientSecret;

		/**
		 * Client authentication method. May be left blank when using a pre-defined
		 * provider.
		 */
		private String clientAuthenticationMethod;

		/**
		 * Authorization grant type. May be left blank when using a pre-defined provider.
		 */
		private String authorizationGrantType;

		/**
		 * Redirect URI. May be left blank when using a pre-defined provider.
		 */
		private String redirectUri;

		/**
		 * Authorization scopes. When left blank the provider's default scopes, if any,
		 * will be used.
		 */
		private Set<String> scope;

์ด๋Ÿฌํ•œ ๊ฐ’๋“ค์„ ์…‹ํŒ…ํ•  ์ˆ˜ ์žˆ๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ค์ • ํด๋ž˜์Šค

OAuth2ClientProperties ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์„ ์ฐพ์•„๋ณด๋ฉด

์„ค์ • ์‚ฌ์ง„

์ด๋Ÿฐ ์„ค์ • ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ์„ค์ •์„ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž˜ ๋ณด๋ฉด ClientRegistration์ด ๊ฐ’์— ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ ๋“ค์–ด๊ฐ€๋ฉด

์„ค์ • ์‚ฌ์ง„

oauth2 ํ†ต์‹ ์— ํ•„์š”ํ•œ ๊ฐ’๋“ค์ด ๋ญ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์ธ๊ฐ€ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ธ์ฆ ์„œ๋ฒ„ ์ œ๊ณต์ž

์šฐ๋ฆฌ๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ธ์ฆ ์„œ๋ฒ„ ์ œ๊ณต์ž๋Š” ์–ด๋–ป๊ฒŒ ํŠน์ • ๊ฐ’์„ ์…‹ํŒ… ์•ˆํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๊ฑธ๊นŒ?

public enum CommonOAuth2Provider {

	GOOGLE {

		@Override
		public Builder getBuilder(String registrationId) {
			ClientRegistration.Builder builder = getBuilder(registrationId,
					ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
			builder.scope("openid", "profile", "email");
			builder.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
			builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
			builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
			builder.issuerUri("https://accounts.google.com");
			builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
			builder.userNameAttributeName(IdTokenClaimNames.SUB);
			builder.clientName("Google");
			return builder;
		}

	},

	GITHUB {

		@Override
		public Builder getBuilder(String registrationId) {
			ClientRegistration.Builder builder = getBuilder(registrationId,
					ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
			builder.scope("read:user");
			builder.authorizationUri("https://github.com/login/oauth/authorize");
			builder.tokenUri("https://github.com/login/oauth/access_token");
			builder.userInfoUri("https://api.github.com/user");
			builder.userNameAttributeName("id");
			builder.clientName("GitHub");
			return builder;
		}

	},

	FACEBOOK {

		@Override
		public Builder getBuilder(String registrationId) {
			ClientRegistration.Builder builder = getBuilder(registrationId,
					ClientAuthenticationMethod.CLIENT_SECRET_POST, DEFAULT_REDIRECT_URL);
			builder.scope("public_profile", "email");
			builder.authorizationUri("https://www.facebook.com/v2.8/dialog/oauth");
			builder.tokenUri("https://graph.facebook.com/v2.8/oauth/access_token");
			builder.userInfoUri("https://graph.facebook.com/me?fields=id,name,email");
			builder.userNameAttributeName("id");
			builder.clientName("Facebook");
			return builder;
		}

	},

	OKTA {

		@Override
		public Builder getBuilder(String registrationId) {
			ClientRegistration.Builder builder = getBuilder(registrationId,
					ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
			builder.scope("openid", "profile", "email");
			builder.userNameAttributeName(IdTokenClaimNames.SUB);
			builder.clientName("Okta");
			return builder;
		}

	};

	private static final String DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}";

	protected final ClientRegistration.Builder getBuilder(String registrationId, ClientAuthenticationMethod method,
			String redirectUri) {
		ClientRegistration.Builder builder = ClientRegistration.withRegistrationId(registrationId);
		builder.clientAuthenticationMethod(method);
		builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
		builder.redirectUri(redirectUri);
		return builder;
	}

	/**
	 * Create a new
	 * {@link org.springframework.security.oauth2.client.registration.ClientRegistration.Builder
	 * ClientRegistration.Builder} pre-configured with provider defaults.
	 * @param registrationId the registration-id used with the new builder
	 * @return a builder instance
	 */
	public abstract ClientRegistration.Builder getBuilder(String registrationId);

}

์œ„ ์ฒ˜๋Ÿผ Common Builder์— ์ •์˜ ๋˜์–ด์žˆ๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋กœ ์ธํ•ด์„œ yml์— ์ถ”๊ฐ€๋กœ ์ž‘์„ฑ์„ ์•ˆํ•ด๋„ ๋™์ž‘์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

OAuth2 ๊ตฌ๋™์˜ ์ดํ•ด

  1. OAuth2๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋ฉด ๋จผ์ € ClientRegistration Repository ๋นˆ์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์—†์œผ๋ฉด ClientRegistration Repository์ด ๋นˆ์„ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.

  2. ์ดํ›„ OAuth2ClientPropertiesMapper์ด ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด์„œ ClientRegistrations ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค. ์„ค์ • ์‚ฌ์ง„

  3. ๊ทธ๋ฆฌ๊ณ  ์ธ๊ฐ€ ์„œ๋ฒ„์— ๋Œ€ํ•œ base url๋ฅผ ์ง€์ •ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด url์„ ๊ฐ€์ง€๊ณ  ํ†ต์‹ ํ•ด์„œ ์ธ๊ฐ€ ์„œ๋ฒ„์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๊ฒŒ ๋œ๋‹ค. ์„ค์ • ์‚ฌ์ง„

2๊ฐ€์ง€์˜ ๋ฐฉ์‹์ด ์กด์žฌํ•˜๋Š”๋ฐ oidc ๋ฐฉ์‹๊ณผ oauth ๋ฐฉ์‹์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ์ด ClientRegistrations ํด๋ž˜์Šค์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ClientAuthenticationMethod ์ด ํด๋ž˜์Šค์— ๋“ค์–ด๊ฐ€๋ฉด ์–ด๋– ํ•œ ํƒ€์ž…์„ ์ง€์›ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. RestTemplate๋ฅผ ํ†ตํ•ด์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์„œ MapConfiguration์„ ํ•˜๊ณ  OIDCProviderMetadata๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. โ†’ map์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค๋Š” ๋ง
  2. ์ตœ์ข…์ ์œผ๋กœ ClientRegistration๋กœ ์ƒ์„ฑ ๋ฐ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋œ๋‹ค.

โ†’ ์—ฌ๊ธฐ์„œ MapConfiguration์„ ํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ ์šฐ๋ฆฌ๊ฐ€ ๋”ฐ๋กœ application.yml์— ์„ค์ •์„ ์•ˆํ•  ๊ฒฝ์šฐ์— ์ž๋™์œผ๋กœ ๋˜๋Š” ๊ฒƒ์ด๊ณ  ๋”ฐ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ ๋œ๋‹ค.

yml ์„ค์ •

๋ณธ์ธ์€ yml ์„ค์ •์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰ํ•˜์˜€๋‹ค.

server:
    port: 8081

spring:
    security:
        oauth2:
            client:
                registration:
                    keycloak:
                        client-id: oauth2-client-app
                        client-secret: zlvRZaTJGI2dEPwDCXMJBWXL3HdQhpWe
                        client-name: client-app
                        redirect-uri: http://localhost:8081/login/oauth2/code/keycloak
                        authorization-grant-type: authorization_code
                        client-authentication-method: client_secret_basic
                        scope: openid, profile, email
                provider:
                    keycloak:
                        authorization-uri: http://localhost/realms/oauth2/protocol/openid-connect/auth
                        token-uri: http://localhost/realms/oauth2/protocol/openid-connect/token
                        issuer-uri: http://localhost/realms/oauth2
                        user-info-uri: http://localhost/realms/oauth2/protocol/openid-connect/userinfo
                        jwk-set-uri: http://localhost/realms/oauth2/protocol/openid-connect/certs
                        user-name-attribute: preferred_username

๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๊ฐ’๋“ค์ด ๋ณด๋‹ˆ๊นŒ ๋‹ค ์ธ๊ฐ€ ์„œ๋ฒ„์™€ ํ†ต์‹ ์„ ํ†ตํ•ด์„œ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿผ ํ•„์š”์—†๋Š” ๊ฐ’๊นŒ์ง€ ์…‹ํŒ…ํ•œ ๊ฒƒ์ธ๋ฐ

server:
    port: 8081

spring:
    security:
        oauth2:
            client:
                registration:
                    keycloak:
                        client-id: oauth2-client-app
                        client-secret: zlvRZaTJGI2dEPwDCXMJBWXL3HdQhpWe
                        redirect-uri: http://localhost:8081/login/oauth2/code/keycloak
						scope: openid, profile, email
                provider:
                    keycloak:
                        issuer-uri: http://localhost/realms/oauth2

์ด๋ ‡๊ฒŒ ๊ฐ„๋žตํ™” ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

์œ„์ฒ˜๋Ÿผ ๊ผญ ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๋‘๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ์ด์Šˆ์–ด๋Š” ์ธ๊ฐ€ ์„œ๋ฒ„์˜ ์ฃผ์†Œ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๊ฐ’, ํด๋ผ์ด์–ธํŠธ id, secret๊ฐ’์€ ์ธ๊ฐ€ ์„œ๋ฒ„๋งˆ๋‹ค ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๊ฐ’, redirect ๊ฐ’๋„ ํ•„์ˆ˜ ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ์ง„ํ–‰ํ•˜๊ณ  scope๋„ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ํ•„์ˆ˜๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ํ•ด์„œ ์‹คํ–‰ํ•ด๋ณด๋ฉด

๋””๋ฒ„๊ทธ ํ™•์ธ

์„ค์ • ์‚ฌ์ง„

๋‚ด๊ฐ€ ์„ค์ •ํ•œ ๊ฐ’์ธ keycloak ๊ฐ’๊ณผ ์„ค์ • ํŒŒ์ผ์˜ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๊ณ  ์ดํ›„ ์ด์Šˆ์–ด๋ฅผ ํ†ตํ•ด์„œ ๋‚˜๋จธ์ง€์˜ ๊ฐ’๋“ค์„ ๊ฐ€์ง€๊ณ  ์˜ค๋Š”์ง€ ํ™•์ธํ•ด๋ณด๋ฉด

์„ค์ • ์‚ฌ์ง„

์ด ์‹œ์ ์—์„œ ์‹œ์ž‘์ด ๋˜๋‹ˆ๊นŒ

์„ค์ • ์‚ฌ์ง„

๋งˆ์ง€๋ง‰ builder์— ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ๊ฐ’์„ ํ™•์ธํ•ด๋ณด๋ฉด yml์— ์„ค์ •ํ•ด์ค€ ๊ฐ’๋“ค์ด ๋‹ค ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋Š” ์ธ๊ฐ€ ์„œ๋ฒ„์˜ ์ฃผ์†Œ๋ฅผ ์ ์–ด์ฃผ๊ฒŒ ๋˜๋ฉด ์ธ๊ฐ€ ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด์„œ

authorization-uri: http://localhost/realms/oauth2/protocol/openid-connect/auth
token-uri: http://localhost/realms/oauth2/protocol/openid-connect/token
user-info-uri: http://localhost/realms/oauth2/protocol/openid-connect/userinfo
jwk-set-uri: http://localhost/realms/oauth2/protocol/openid-connect/certs
user-name-attribute: preferred_username

์ด๋Ÿฐ ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด๋“ค์„ ๋ฐ›์•„์˜ค๊ฒŒ ๋˜๋Š”๋ฐ ์•„๊นŒ์ „์— ์–ธ๊ธ‰ํ•œ Common oauth2 ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ์—” ์ด๋ฏธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ž‘์„ฑ์ด ๋˜์–ด์žˆ๋Š”๋ฐ provider์— ์ด์Šˆ์–ด๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ์•ˆํ•ด๋„ ๋  ํ†ต์‹ ์„ ํ•œ๋ฒˆ ๋” ํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

Common oauth2 ์—ฐ๊ฒฐ

๊ทธ๋ ‡๋‹ค๋ฉด ๋งŒ์•ฝ ๊ธฐ๋ณธ ์ œ๊ณต์ž๊ฐ€ ์žˆ๋‹ค๋ฉด provider ๊ฐ’์ด ํ•„์š”ํ• ๊นŒ? common provider์— ๊ธฐ๋ณธ์ ์ธ ์ œ๊ณต์ž ๊ฐ’์ด ์กด์žฌํ•˜๋Š”๋ฐ issuer-uri ๊ฐ’์„ ์…‹ํŒ…ํ•˜๋ฉด ์กด์žฌํ•˜๋Š”๋ฐ ํ•œ๋ฒˆ ๋” ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ํ•„์š” ์—†๋‹ค. ์ œ๊ณต์ž๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  ์ž‘์„ฑํ•˜์ž (redirect ๊ฐ’๋„ ํ•„์š” ์—†๋‹ค. client id์™€ secret ๊ฐ’๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค.)

์•„ํ‚คํ…์ฒ˜ ๊ตฌ์„ฑ 1

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors