๐Ÿงญ Keycloak ๊ธฐ๋ฐ˜ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ธ์ฆ ๊ตฌ์กฐ & ์‹ค์ „ ๊ตฌ์„ฑ

okorionยท2025๋…„ 10์›” 6์ผ

๐Ÿ” Spring Security 6

๋ชฉ๋ก ๋ณด๊ธฐ
8/10

OAuth2์™€ OpenID Connect๋ฅผ ์‹ค๋ฌด ์ˆ˜์ค€์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ํ˜„์‹ค์ ์ธ ์ ‘๊ทผ


๐Ÿ“˜ ๋“ค์–ด๊ฐ€๋ฉฐ โ€” ์™œ OAuth2๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•œ๊ฐ€

JWT๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ Stateless ์ธ์ฆ์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ,

๊ธฐ์—… ํ™˜๊ฒฝ(Enterprise)์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜„์‹ค์ ์ธ ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค.

๋ฌธ์ œ์„ค๋ช…
์ค‘์•™์ง‘์ค‘ํ˜• ์ธ์ฆ ๋ถ€์žฌ๊ฐ ์„œ๋น„์Šค๊ฐ€ ์ง์ ‘ ๋กœ๊ทธ์ธยทํ† ํฐ ๋ฐœ๊ธ‰ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
์กฐ์ง ๋‚ด ๋‹ค์ค‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ด€๋ฆฌ ์–ด๋ ค์›€์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ ๊ฐ„ ๊ณ„์ •, ๊ถŒํ•œ, ์—ญํ• ์„ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ต๋‹ค
๋ณด์•ˆ ๊ทœ์ • ์ค€์ˆ˜ ๋ฌธ์ œOAuth2๋งŒ์œผ๋กœ๋Š” SSO, MFA, LDAP, SAML ๊ฐ™์€ ๊ธฐ์—… ์š”๊ตฌ ๋Œ€์‘์ด ์ œํ•œ์ 
์šด์˜ ํšจ์œจ์„ฑ ์ €ํ•˜์‚ฌ์šฉ์žยท๊ถŒํ•œ ๋ณ€๊ฒฝ ์‹œ ๋ชจ๋“  ์„œ๋น„์Šค ๋ฐฐํฌ ํ•„์š”

โžก๏ธ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด Keycloak์ด๋‹ค.


#1. Keycloak ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

Keycloak์€ Red Hat์ด ์ฃผ๋„ํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค ์ธ์ฆยท์ธ๊ฐ€ ์„œ๋ฒ„์ด๋‹ค.

OAuth2, OpenID Connect(OIDC), SAML 2.0, LDAP ์—ฐ๋™, SSO๊นŒ์ง€ ์™„๋น„๋œ

Identity and Access Management (IAM) ์†”๋ฃจ์…˜์ด๋‹ค.

ํ•ญ๋ชฉ์„ค๋ช…
๊ธฐ๋ฐ˜ ํ”„๋กœํ† ์ฝœOAuth2, OpenID Connect, SAML
์ฃผ์š” ๊ธฐ๋Šฅ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ, ์‚ฌ์šฉ์ž ๋“ฑ๋ก, ๋น„๋ฐ€๋ฒˆํ˜ธ ์ •์ฑ…, MFA, ์„ธ์…˜ ๊ด€๋ฆฌ
์—ฐ๋™ ๋ฐฉ์‹REST API / OIDC Discovery / JWT Token
๋ฐฐํฌ ๋ฐฉ๋ฒ•Docker, Kubernetes, Standalone JAR, Operator
Spring ์—ฐ๋™ ๋ฐฉ์‹spring-boot-starter-oauth2-resource-server ๋˜๋Š” spring-boot-starter-oauth2-client

#2. Keycloak ๊ตฌ์กฐ ํ•œ๋ˆˆ์— ๋ณด๊ธฐ

์š”์•ฝ

  • Realm: ํ•˜๋‚˜์˜ ์ธ์ฆ ์˜์—ญ (ํšŒ์‚ฌ / ์„œ๋น„์Šค ๋‹จ์œ„)
  • Client: OAuth2 ํด๋ผ์ด์–ธํŠธ (Angular, Spring Boot ๋“ฑ)
  • User: Keycloak ๋‚ด ์‚ฌ์šฉ์ž
  • Role: ์—ญํ•  ๊ธฐ๋ฐ˜ ๊ถŒํ•œ ์„ค์ •
  • Flow: OAuth2 Authorization Code + PKCE

#3. Docker๋กœ Keycloak ์„ค์น˜

docker run -d \
  --name keycloak \
  -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:24.0.4 start-dev

์ ‘์†

http://localhost:8080
  • Username: admin
  • Password: admin

#4. Realm, Client, User ๊ตฌ์„ฑ

1๏ธโƒฃ Realm ์ƒ์„ฑ

  • Add Realm โ†’ eazybank

2๏ธโƒฃ Client ๋“ฑ๋ก

  • Client ID: eazybank-client
  • Protocol: openid-connect
  • Access Type: public
  • Redirect URI: http://localhost:4200/*
  • Valid Redirect URIs โ†’ Angular ์•ฑ ์ฃผ์†Œ

3๏ธโƒฃ User ์ƒ์„ฑ

  • Username: happy@example.com
  • Password: password
  • Role Mapping: ROLE_USER

4๏ธโƒฃ Role ์ƒ์„ฑ

  • ROLE_USER, ROLE_ADMIN ๋“ฑ

#5. OAuth2 Grant Type ๋ณต์Šต

Grant Type์„ค๋ช…๋Œ€ํ‘œ ์‚ฌ์šฉ์ฒ˜
Authorization Code๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ฐ˜ ์ธ์ฆ (PKCE ํฌํ•จ)์›น/๋ชจ๋ฐ”์ผ ํด๋ผ์ด์–ธํŠธ
Client Credentials์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ ๋ฐฑ์—”๋“œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค
PasswordDeprecated (์ง์ ‘ ์ž๊ฒฉ์ฆ๋ช… ์ „๋‹ฌ)ํ…Œ์ŠคํŠธ์šฉ๋งŒ
Refresh TokenAccess Token ์žฌ๋ฐœ๊ธ‰์žฅ๊ธฐ ์„ธ์…˜ ๊ด€๋ฆฌ

#6. Authorization Code + PKCE Flow

๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ๋Š” PKCE(Proof Key for Code Exchange) ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


#7. Access Token vs ID Token

๊ตฌ๋ถ„๋ชฉ์ ํฌํ•จ ์ •๋ณด์‚ฌ์šฉ ์œ„์น˜
Access Token๋ฆฌ์†Œ์Šค ์ ‘๊ทผ ์ธ์ฆ๊ถŒํ•œ, Scope, ๋งŒ๋ฃŒ์‹œ๊ฐ„Resource Server
ID Token์‚ฌ์šฉ์ž ์‹๋ณ„์‚ฌ์šฉ์ž ์ด๋ฆ„, ์ด๋ฉ”์ผ, ์ธ์ฆ ์ •๋ณดํด๋ผ์ด์–ธํŠธ ์ธก (UI)
Refresh Tokenํ† ํฐ ๊ฐฑ์‹ ๋งŒ๋ฃŒ์‹œ๊ฐ„, ์„ธ์…˜ ์‹๋ณ„์žAuthorization Server

#8. Spring Boot Resource Server ์„ค์ •

application.yml ์˜ˆ์‹œ:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/realms/eazybank

SecurityConfig.java:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/public/**").permitAll()
            .anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2.jwt());
    return http.build();
}

#9. Postman์œผ๋กœ ๊ฒ€์ฆ

  1. Authorization ํƒญ โ†’ Type: OAuth2

  2. Token URL:

    http://localhost:8080/realms/eazybank/protocol/openid-connect/token
    
  3. Client ID: eazybank-client

  4. Grant Type: Authorization Code

  5. Scope: openid profile email

  6. Callback URL: http://localhost:4200/

ํ† ํฐ ๋ฐœ๊ธ‰ ์„ฑ๊ณต ์‹œ ๋‹ค์Œ ํ•„๋“œ ํ™•์ธ:

{
  "access_token": "...",
  "id_token": "...",
  "refresh_token": "...",
  "expires_in": 300
}

#10. Angular ํด๋ผ์ด์–ธํŠธ ์—ฐ๋™ ํ•ต์‹ฌ ํฌ์ธํŠธ

  • angular-oauth2-oidc ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ
  • ์„ค์ • ํŒŒ์ผ ์˜ˆ์‹œ:
import { AuthConfig } from 'angular-oauth2-oidc';

export const authConfig: AuthConfig = {
  issuer: 'http://localhost:8080/realms/eazybank',
  redirectUri: window.location.origin,
  clientId: 'eazybank-client',
  scope: 'openid profile email',
  responseType: 'code',
  showDebugInformation: true,
  usePkce: true
};

#11. Keycloak ์—ฐ๋™ ํ›„ ์ „์ฒด ์•„ํ‚คํ…์ฒ˜

๊ตฌ์„ฑ์š”์†Œ์„ค๋ช…
Angularํด๋ผ์ด์–ธํŠธ (Auth Code Flow ์ˆ˜ํ–‰)
Keycloak์ธ์ฆยท์ธ๊ฐ€ ์„œ๋ฒ„ (Token ๋ฐœ๊ธ‰)
Spring BootResource Server (JWT ๊ฒ€์ฆ)

#12. Keycloak vs ๋‹ค๋ฅธ ์ธ์ฆ ์„œ๋น„์Šค ๋น„๊ต

๋น„๊ต ํ•ญ๋ชฉKeycloakOktaAWS Cognito
์˜คํ”ˆ์†Œ์Šค ์—ฌ๋ถ€โœ… ์™„์ „ ์˜คํ”ˆ์†Œ์ŠคโŒ ์œ ๋ฃŒ SaaSโœ… ์ œํ•œ์ 
์ž์ฒด ํ˜ธ์ŠคํŒ…โœ… ๊ฐ€๋ŠฅโŒ ๋ถˆ๊ฐ€โœ… ๊ฐ€๋Šฅ
์ง€์› ํ”„๋กœํ† ์ฝœOAuth2, OIDC, SAMLOAuth2, OIDCOAuth2, OIDC
ํ™•์žฅ์„ฑ๋†’์Œ (Plugin, SPI)์ค‘๊ฐ„๋‚ฎ์Œ
ํ†ตํ•ฉ ๊ด€๋ฆฌRealm ๋‹จ์œ„ ๊ด€๋ฆฌ์กฐ์ง ๋‹จ์œ„ ๊ด€๋ฆฌUser Pool ๋‹จ์œ„ ๊ด€๋ฆฌ

#13. ๋ณด์•ˆ ์šด์˜ ํŒ (์‹ค๋ฌด ๊ธฐ์ค€)

์˜์—ญ๋ชจ๋ฒ” ์‚ฌ๋ก€
Secret ๊ด€๋ฆฌ.env or Vault, ์ ˆ๋Œ€ ์ฝ”๋“œ์— ํฌํ•จํ•˜์ง€ ์•Š๊ธฐ
SSL/TLSKeycloak ๋ฐ API ๋ชจ๋‘ HTTPS ํ•„์ˆ˜
Token ์ˆ˜๋ช…Access 5~15๋ถ„ / Refresh 30๋ถ„ ์ดํ•˜
Role/Scope ์ „๋žตAPI๋ณ„ ์ตœ์†Œ ๊ถŒํ•œ ์„ค๊ณ„ (RBAC ์›์น™)
MonitoringKeycloak Admin Console + Grafana + Loki ์—ฐ๋™
BackupRealm Export JSON ์ฃผ๊ธฐ์  ๋ฐฑ์—…

#14. Keycloak์˜ ์œ„์น˜ โ€” OAuth2 ์ง„ํ™” ๊ตฌ์กฐ ์š”์•ฝ

Keycloak์€ ๋‹จ์ˆœํ•œ โ€œ๋ณด์•ˆ ์„œ๋ฒ„โ€๊ฐ€ ์•„๋‹ˆ๋ผ,

OAuth2์™€ OIDC๋ฅผ ํ†ตํ•ฉ ๊ด€๋ฆฌ ๊ฐ€๋Šฅํ•œ ํ”Œ๋žซํผ์œผ๋กœ ์ง„ํ™”์‹œํ‚จ ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.


#15. ๊ฒฐ๋ก  โ€” Keycloak์ด ์ฃผ๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ด์ 

โœ… Single Sign-On (SSO)

โœ… Centralized Role Management

โœ… OAuth2 / OIDC / SAML ํ†ตํ•ฉ ์ง€์›

โœ… LDAP / AD ์—ฐ๋™

โœ… API Gateway์™€ ์—ฐ๋™ ์šฉ์ด (Kong, Nginx, Istio)

โœ… MFA / OTP / Social Login ํ†ตํ•ฉ

Keycloak์„ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” โ€œ๊ฐ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๊ฐ€ ์ง์ ‘ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ตฌ์กฐโ€์—์„œ โ€œํ•˜๋‚˜์˜ ์ค‘์•™ ์ธ์ฆ ํ—ˆ๋ธŒ๋ฅผ ๋‘๋Š” ๊ตฌ์กฐโ€๋กœ ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ๋‹ค.

profile
Tech Blog

0๊ฐœ์˜ ๋Œ“๊ธ€