본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Keycloak

원문 보기 위키 갱신

Keycloak (Keycloak 컴포넌트)

Keycloak 컴포넌트는 Keycloak 인스턴스에 대한 관리 연산 수행과 정책 강제(policy enforcement)를 지원하는 컴포넌트예요. Camel 4.15부터 제공됐고 producer와 consumer를 모두 지원합니다. Admin API 기반의 realm·사용자·역할·클라이언트·그룹 관리 연산, 이벤트 폴링 컨슈머, 라우트 수준 시큐리티 정책(role/permission 기반 인가와 OAuth 2.0 토큰 인트로스펙션)을 제공해요.

출처: 문서

본문

Camel 4.15부터 지원

producer와 consumer를 모두 지원해요

Keycloak 컴포넌트는 Keycloak 인스턴스에 연산을 실행하고 정책 강제(policy enforcement)를 수행하는 기능을 지원해요.

컴포넌트 기능 (Component Features)

Keycloak 컴포넌트는 세 가지 주요 기능을 제공해요:

  1. Producer Operations - Admin API를 통해 Keycloak 인스턴스를 관리해요(realm, 사용자, 역할, 클라이언트, 그룹, 세션, 토큰 등)

  2. Consumer Operations - 모니터링, 감사(auditing), 이벤트 기반 워크플로를 위해 Keycloak에서 사용자 이벤트와 관리자 이벤트를 폴링하고 소비해요

  3. Security Policies - 역할 기반 접근, 권한 기반 접근, OAuth 2.0 토큰 인트로스펙션(introspection)을 포함해 Keycloak 인증·권한 부여 서비스로 라우트 수준 인가를 제공해요

URI 형식 (URI Format)

keycloak://label[?options]

다음 형식으로 URI에 쿼리 옵션을 붙일 수 있어요:

?options=value&option2=value&…​

옵션 설정 방법 (Configuring Options)

Camel 컴포넌트는 서로 다른 두 단계로 설정해요:

  • 컴포넌트(component) 레벨

  • 엔드포인트(endpoint) 레벨

컴포넌트 옵션 설정 (Configuring Component Options)

컴포넌트 레벨에서는 엔드포인트들이 이어서 물려받는 일반적이고 공유되는 설정을 해요. 가장 상위의 설정 레벨이죠.

예를 들어 컴포넌트에는 보안 설정, 인증용 자격 증명, 네트워크 연결 URL 같은 것들이 있을 수 있어요.

컴포넌트에 따라 옵션이 몇 개뿐인 것도 있고 아주 많은 것도 있어요. 컴포넌트는 보통 널리 쓰이는 기본값이 미리 설정되어 있어서, 몇 가지 옵션만 설정하거나 아예 하나도 건드리지 않아도 되는 경우가 많아요.

컴포넌트는 다음 방법으로 설정할 수 있어요:

  • the Component DSL.

  • 설정 파일(application.properties, *.yaml 파일 등).

  • Java 코드에서 직접.

엔드포인트 옵션 설정 (Configuring Endpoint Options)

엔드포인트는 옵션이 많아서 설정에 시간을 더 쓰게 될 거예요. 이 옵션들이 엔드포인트가 원하는 일을 하도록 커스터마이즈해 줘요. 옵션은 엔드포인트가 consumer(from)로 쓰이는지, producer(to)로 쓰이는지, 둘 다인지에 따라 분류되기도 해요.

엔드포인트 설정은 대부분 엔드포인트 URI에 _path_와 query 파라미터로 바로 하는 경우가 많아요. Java에서 엔드포인트와 데이터 포맷을 _타입 세이프_하게 설정하려면 Endpoint DSL과 DataFormat DSL을 쓸 수도 있어요.

옵션을 설정할 때 좋은 습관은 Property Placeholders를 사용하는 거예요.

프로퍼티 플레이스홀더는 이런 장점이 있어요:

  • URL, 포트 번호, 민감한 정보 같은 설정을 하드코딩하는 걸 막아 줘요.

  • 설정을 코드 밖으로 분리할 수 있어요.

  • 코드가 더 유연해지고 재사용하기 좋아져요.

다음 두 섹션에서 모든 옵션을 나열해요. 먼저 컴포넌트 옵션, 그다음 엔드포인트 옵션 순서예요.

컴포넌트 옵션 (Component Options)

Keycloak 컴포넌트가 지원하는 옵션은 아래와 같아요.

Name Description Default Type
accessToken (common) 인증에 쓸 미리 발급받은 액세스 토큰이에요. 이 값을 주면 username/password나 client credentials 흐름으로 토큰을 발급받는 대신 이 토큰을 바로 사용해요. String
authClient (common) 인증 클라이언트 ID로 관리자 이벤트를 필터링해요. String
authIpAddress (common) 인증 IP 주소로 관리자 이벤트를 필터링해요. String
authRealm (common) 인증에 사용할 Keycloak realm이에요. 지정하지 않으면 realm 파라미터가 인증에 쓰여요. 한 realm(예: master)으로 인증하고 다른 realm에 연산을 수행하고 싶을 때 유용해요. master String
authRealmFilter (common) 인증 realm으로 관리자 이벤트를 필터링해요. String
authUser (common) 인증 사용자 ID로 관리자 이벤트를 필터링해요. String
client (common) 클라이언트 ID로 이벤트를 필터링해요. String
clientId (common) Keycloak 클라이언트 ID예요. String
clientSecret (common) Keycloak 클라이언트 시크릿이에요. String
configuration (common) 컴포넌트 설정이에요. KeycloakConfiguration
dateFrom (common) epoch 이후 밀리초 단위 시작 날짜/시각으로 이벤트를 필터링해요. String
dateTo (common) epoch 이후 밀리초 단위 종료 날짜/시각으로 이벤트를 필터링해요. String
eventType (common) 소비할 이벤트 타입이에요: events 또는 admin-events. events String
first (common) 페이지네이션 오프셋(첫 결과 인덱스)이에요. 0 int
introspectionCacheEnabled (common) Keycloak으로의 API 호출을 줄이려고 토큰 인트로스펙션 결과 캐싱을 켜요. true boolean
introspectionCacheTtl (common) 캐시된 인트로스펙션 결과의 유지 시간(TTL, 초)이에요. 60 long
ipAddress (common) IP 주소로 이벤트를 필터링해요. String
keycloakClient (common) Autowired 이미 설정된 Keycloak 관리자 클라이언트를 사용해요. Keycloak
maxResults (common) 폴링당 가져올 이벤트 최대 개수예요. 100 int
operation (common)
수행할 연산이에요.

Enum values:

  • createRealm

  • deleteRealm

  • getRealm

  • updateRealm

  • createUser

  • deleteUser

  • getUser

  • updateUser

  • listUsers

  • searchUsers

  • createRole

  • deleteRole

  • getRole

  • updateRole

  • listRoles

  • assignRoleToUser

  • removeRoleFromUser

  • getUserRoles

  • createGroup

  • deleteGroup

  • getGroup

  • updateGroup

  • listGroups

  • addUserToGroup

  • removeUserFromGroup

  • listUserGroups

  • createClient

  • deleteClient

  • getClient

  • updateClient

  • listClients

  • resetUserPassword

  • createClientRole

  • deleteClientRole

  • getClientRole

  • updateClientRole

  • listClientRoles

  • assignClientRoleToUser

  • removeClientRoleFromUser

  • listUserSessions

  • logoutUser

  • logoutAllUsers

  • revokeAccessToken

  • revokeRefreshToken

  • introspectToken

  • pushNotBefore

  • createClientScope

  • deleteClientScope

  • getClientScope

  • updateClientScope

  • listClientScopes

  • createIdentityProvider

  • deleteIdentityProvider

  • getIdentityProvider

  • updateIdentityProvider

  • listIdentityProviders

  • createResource

  • deleteResource

  • getResource

  • updateResource

  • listResources

  • createResourcePolicy

  • deleteResourcePolicy

  • getResourcePolicy

  • updateResourcePolicy

  • listResourcePolicies

  • createResourcePermission

  • deleteResourcePermission

  • getResourcePermission

  • updateResourcePermission

  • listResourcePermissions

  • evaluatePermission

  • getUserAttributes

  • setUserAttribute

  • deleteUserAttribute

  • getUserCredentials

  • deleteUserCredential

  • sendVerifyEmail

  • sendPasswordResetEmail

  • addRequiredAction

  • removeRequiredAction

  • executeActionsEmail

  • getClientSecret

  • regenerateClientSecret

  • bulkCreateUsers

  • bulkDeleteUsers

  • bulkAssignRolesToUser

  • bulkAssignRoleToUsers

  • bulkUpdateUsers

  • createOrganization

  • updateOrganization

  • deleteOrganization

  • getOrganization

  • listOrganizations

  • searchOrganizations

  • addOrganizationMember

  • removeOrganizationMember

  • listOrganizationMembers

  • linkOrganizationIdentityProvider

  • unlinkOrganizationIdentityProvider

  • listOrganizationIdentityProviders

  • addFederatedIdentity

  • removeFederatedIdentity

  • getFederatedIdentities

| | KeycloakOperations | | operationTypes (common) | 연산 타입으로 관리자 이벤트를 필터링해요(쉼표로 구분한 목록, 예: CREATE,UPDATE,DELETE). | | String | | password (common) | Keycloak 비밀번호예요. | | String | | pojoRequest (common) | POJO 요청을 본문으로 쓸지 여부예요. | false | boolean | | realm (common) | Keycloak realm이에요. 보통 모든 연산은 master realm에서 시작하기 때문에 기본값은 master예요. | master | String | | resourcePath (common) | 리소스 경로로 관리자 이벤트를 필터링해요. | | String | | serverUrl (common) | Keycloak 서버 URL이에요. | | String | | types (common) | 이벤트 타입으로 이벤트를 필터링해요(쉼표로 구분한 목록, 예: LOGIN,LOGOUT). | | String | | user (common) | 사용자 ID로 이벤트를 필터링해요. | | String | | username (common) | Keycloak 사용자 이름이에요. | | String | | useTokenIntrospection (common) | 실시간 토큰 검증을 위해 OAuth 2.0 토큰 인트로스펙션을 켜요. 켜면 로컬 JWT 파싱 대신 Keycloak의 인트로스펙션 엔드포인트를 호출해서 토큰을 검증해요. 만료 전에 폐기된 토큰을 감지할 수 있어요. | false | boolean | | bridgeErrorHandler (consumer) | 컨슈머를 Camel 라우팅 에러 핸들러에 연결(bridge)해요. 그러면 Camel 컨슈머가 들어오는 메시지를 가져오는 동안 발생한 예외도 (가능하면) 메시지로 처리돼서 라우팅 에러 핸들러가 다루게 돼요. 중요: 이 기능은 서드파티 컴포넌트가 예외가 던져졌을 때 Camel에 알려줄 수 있을 때만 가능해요. 일부 컴포넌트는 내부에서만 처리하기 때문에 bridgeErrorHandler를 쓸 수 없어요. 다른 경우에는 향후 릴리스에서 서드파티 컴포넌트에 연결(hook)되도록 Camel 컴포넌트를 개선할 수 있어요. 기본값으로 컨슈머는 org.apache.camel.spi.ExceptionHandler를 써서 예외를 WARN 또는 ERROR 레벨로 로깅하고 무시해요. | false | boolean | | lazyStartProducer (producer) | producer를 lazy(첫 메시지 시점)로 시작할지 여부예요. lazy 시작을 쓰면 producer가 시작 중 실패해서 라우트 시작이 실패하는 상황에서도 CamelContext와 라우트를 시작할 수 있어요. 시작을 늦추면 시작 실패를 Camel의 라우팅 에러 핸들러로 메시지 라우팅 중에 처리할 수 있죠. 다만 첫 메시지를 처리하는 시점에 producer를 만들고 시작하는 데 시간이 조금 걸려서 전체 처리 시간이 길어질 수 있다는 점은 유의하세요. | false | boolean | | autowiredEnabled (advanced) | 오토와이어링 사용 여부예요. 레지스트리에서 일치하는 타입의 인스턴스가 하나만 있는지 찾아서 컴포넌트에 자동으로 설정하는(옵션이 autowired로 표시돼 있어야 함) 자동 오토와이어링에 쓰입니다. JDBC 데이터 소스, JMS 커넥션 팩토리, AWS 클라이언트 등을 자동 설정할 때 유용해요. | true | boolean |

엔드포인트 옵션 (Endpoint Options)

Keycloak 엔드포인트는 다음 URI 문법으로 설정해요:

keycloak:label

다음 _path_와 query 파라미터를 씁니다:

경로 파라미터 (Path Parameters)

Name Description Default Type
label (common) 필수 논리적 이름이에요. String

쿼리 파라미터 (Query Parameters)

Name Description Default Type
accessToken (common) 인증에 쓸 미리 발급받은 액세스 토큰이에요. 이 값을 주면 username/password나 client credentials 흐름으로 토큰을 발급받는 대신 이 토큰을 바로 사용해요. String
authClient (common) 인증 클라이언트 ID로 관리자 이벤트를 필터링해요. String
authIpAddress (common) 인증 IP 주소로 관리자 이벤트를 필터링해요. String
authRealm (common) 인증에 사용할 Keycloak realm이에요. 지정하지 않으면 realm 파라미터가 인증에 쓰여요. 한 realm(예: master)으로 인증하고 다른 realm에 연산을 수행하고 싶을 때 유용해요. master String
authRealmFilter (common) 인증 realm으로 관리자 이벤트를 필터링해요. String
authUser (common) 인증 사용자 ID로 관리자 이벤트를 필터링해요. String
client (common) 클라이언트 ID로 이벤트를 필터링해요. String
clientId (common) Keycloak 클라이언트 ID예요. String
clientSecret (common) Keycloak 클라이언트 시크릿이에요. String
dateFrom (common) epoch 이후 밀리초 단위 시작 날짜/시각으로 이벤트를 필터링해요. String
dateTo (common) epoch 이후 밀리초 단위 종료 날짜/시각으로 이벤트를 필터링해요. String
eventType (common) 소비할 이벤트 타입이에요: events 또는 admin-events. events String
first (common) 페이지네이션 오프셋(첫 결과 인덱스)이에요. 0 int
introspectionCacheEnabled (common) Keycloak으로의 API 호출을 줄이려고 토큰 인트로스펙션 결과 캐싱을 켜요. true boolean
introspectionCacheTtl (common) 캐시된 인트로스펙션 결과의 유지 시간(TTL, 초)이에요. 60 long
ipAddress (common) IP 주소로 이벤트를 필터링해요. String
keycloakClient (common) Autowired 이미 설정된 Keycloak 관리자 클라이언트를 사용해요. Keycloak
maxResults (common) 폴링당 가져올 이벤트 최대 개수예요. 100 int
operation (common)
수행할 연산이에요.

Enum values:

  • createRealm

  • deleteRealm

  • getRealm

  • updateRealm

  • createUser

  • deleteUser

  • getUser

  • updateUser

  • listUsers

  • searchUsers

  • createRole

  • deleteRole

  • getRole

  • updateRole

  • listRoles

  • assignRoleToUser

  • removeRoleFromUser

  • getUserRoles

  • createGroup

  • deleteGroup

  • getGroup

  • updateGroup

  • listGroups

  • addUserToGroup

  • removeUserFromGroup

  • listUserGroups

  • createClient

  • deleteClient

  • getClient

  • updateClient

  • listClients

  • resetUserPassword

  • createClientRole

  • deleteClientRole

  • getClientRole

  • updateClientRole

  • listClientRoles

  • assignClientRoleToUser

  • removeClientRoleFromUser

  • listUserSessions

  • logoutUser

  • logoutAllUsers

  • revokeAccessToken

  • revokeRefreshToken

  • introspectToken

  • pushNotBefore

  • createClientScope

  • deleteClientScope

  • getClientScope

  • updateClientScope

  • listClientScopes

  • createIdentityProvider

  • deleteIdentityProvider

  • getIdentityProvider

  • updateIdentityProvider

  • listIdentityProviders

  • createResource

  • deleteResource

  • getResource

  • updateResource

  • listResources

  • createResourcePolicy

  • deleteResourcePolicy

  • getResourcePolicy

  • updateResourcePolicy

  • listResourcePolicies

  • createResourcePermission

  • deleteResourcePermission

  • getResourcePermission

  • updateResourcePermission

  • listResourcePermissions

  • evaluatePermission

  • getUserAttributes

  • setUserAttribute

  • deleteUserAttribute

  • getUserCredentials

  • deleteUserCredential

  • sendVerifyEmail

  • sendPasswordResetEmail

  • addRequiredAction

  • removeRequiredAction

  • executeActionsEmail

  • getClientSecret

  • regenerateClientSecret

  • bulkCreateUsers

  • bulkDeleteUsers

  • bulkAssignRolesToUser

  • bulkAssignRoleToUsers

  • bulkUpdateUsers

  • createOrganization

  • updateOrganization

  • deleteOrganization

  • getOrganization

  • listOrganizations

  • searchOrganizations

  • addOrganizationMember

  • removeOrganizationMember

  • listOrganizationMembers

  • linkOrganizationIdentityProvider

  • unlinkOrganizationIdentityProvider

  • listOrganizationIdentityProviders

  • addFederatedIdentity

  • removeFederatedIdentity

  • getFederatedIdentities

| | KeycloakOperations | | operationTypes (common) | 연산 타입으로 관리자 이벤트를 필터링해요(쉼표로 구분한 목록, 예: CREATE,UPDATE,DELETE). | | String | | password (common) | Keycloak 비밀번호예요. | | String | | pojoRequest (common) | POJO 요청을 본문으로 쓸지 여부예요. | false | boolean | | realm (common) | Keycloak realm이에요. 보통 모든 연산은 master realm에서 시작하기 때문에 기본값은 master예요. | master | String | | resourcePath (common) | 리소스 경로로 관리자 이벤트를 필터링해요. | | String | | serverUrl (common) | Keycloak 서버 URL이에요. | | String | | types (common) | 이벤트 타입으로 이벤트를 필터링해요(쉼표로 구분한 목록, 예: LOGIN,LOGOUT). | | String | | user (common) | 사용자 ID로 이벤트를 필터링해요. | | String | | username (common) | Keycloak 사용자 이름이에요. | | String | | useTokenIntrospection (common) | 실시간 토큰 검증을 위해 OAuth 2.0 토큰 인트로스펙션을 켜요. 켜면 로컬 JWT 파싱 대신 Keycloak의 인트로스펙션 엔드포인트를 호출해서 토큰을 검증해요. 만료 전에 폐기된 토큰을 감지할 수 있어요. | false | boolean | | sendEmptyMessageWhenIdle (consumer) | 폴링 컨슈머가 아무것도 가져오지 못했을 때 이 옵션을 켜면 빈 메시지(본문 없음)를 대신 보내요. | false | boolean | | bridgeErrorHandler (consumer (advanced)) | 컨슈머를 Camel 라우팅 에러 핸들러에 연결(bridge)해요. 그러면 Camel 컨슈머가 들어오는 메시지를 가져오는 동안 발생한 예외도 (가능하면) 메시지로 처리돼서 라우팅 에러 핸들러가 다루게 돼요. 중요: 이 기능은 서드파티 컴포넌트가 예외가 던져졌을 때 Camel에 알려줄 수 있을 때만 가능해요. 일부 컴포넌트는 내부에서만 처리하기 때문에 bridgeErrorHandler를 쓸 수 없어요. 다른 경우에는 향후 릴리스에서 서드파티 컴포넌트에 연결(hook)되도록 Camel 컴포넌트를 개선할 수 있어요. 기본값으로 컨슈머는 org.apache.camel.spi.ExceptionHandler를 써서 예외를 WARN 또는 ERROR 레벨로 로깅하고 무시해요. | false | boolean | | exceptionHandler (consumer (advanced)) | 컨슈머가 커스텀 ExceptionHandler를 쓰게 해 줘요. bridgeErrorHandler 옵션이 켜져 있으면 이 옵션은 사용되지 않는다는 점에 유의하세요. 기본값으로 컨슈머는 예외를 WARN 또는 ERROR 레벨로 로깅하고 무시해요. | | ExceptionHandler | | exchangePattern (consumer (advanced)) |

컨슈머가 exchange를 만들 때 exchange 패턴을 설정해요.

Enum values:

  • InOnly

  • InOut

| | ExchangePattern | | pollStrategy (consumer (advanced)) | Exchange가 만들어지고 Camel에서 라우팅되기 전에 폴링 작업 중에 보통 발생하는 에러 처리를 제어할 커스텀 구현을 제공할 수 있게 해 주는 플러그형 org.apache.camel.PollingConsumerPollingStrategy예요. | | PollingConsumerPollStrategy | | lazyStartProducer (producer (advanced)) | producer를 lazy(첫 메시지 시점)로 시작할지 여부예요. lazy 시작을 쓰면 producer가 시작 중 실패해서 라우트 시작이 실패하는 상황에서도 CamelContext와 라우트를 시작할 수 있어요. 시작을 늦추면 시작 실패를 Camel의 라우팅 에러 핸들러로 메시지 라우팅 중에 처리할 수 있죠. 다만 첫 메시지를 처리하는 시점에 producer를 만들고 시작하는 데 시간이 조금 걸려서 전체 처리 시간이 길어질 수 있다는 점은 유의하세요. | false | boolean | | backoffErrorThreshold (scheduler) | backoffMultipler가 작동하기 전에 연속으로 발생해야 하는 에러 폴링(오류로 실패한 폴링) 횟수예요. | | int | | backoffIdleThreshold (scheduler) | backoffMultipler가 작동하기 전에 연속으로 발생해야 하는 유휴(idle) 폴링 횟수예요. | | int | | backoffMultiplier (scheduler) | 연속으로 유휴/에러 폴링이 여러 번 이어졌을 때 예약 폴링 컨슈머가 백오프하도록 해요. 이 배수는 다음 실제 시도가 다시 일어나기 전에 건너뛸 폴링 횟수예요. 이 옵션을 쓰면 backoffIdleThreshold 및/또는 backoffErrorThreshold도 함께 설정해야 해요. | | int | | delay (scheduler) | 다음 폴링 전까지의 밀리초예요. | 500 | long | | greedy (scheduler) | greedy를 켜면 이전 실행이 메시지를 1개 이상 폴링했을 때 ScheduledPollConsumer가 바로 다시 실행돼요. | false | boolean | | initialDelay (scheduler) | 첫 폴링이 시작되기 전까지의 밀리초예요. | 1000 | long | | repeatCount (scheduler) | 발동(fire) 횟수의 최대 한도를 지정해요. 1로 설정하면 스케줄러가 한 번만 발동하고, 5로 설정하면 다섯 번만 발동해요. 0이나 음수는 계속 발동한다는 뜻이에요. | 0 | long | | runLoggingLevel (scheduler) |

컨슈머가 폴링할 때 시작/완료 로그 한 줄을 남겨요. 이 옵션으로 그 로그의 레벨을 설정할 수 있어요.

Enum values:

  • TRACE

  • DEBUG

  • INFO

  • WARN

  • ERROR

  • OFF

| TRACE | LoggingLevel | | scheduledExecutorService (scheduler) | 컨슈머가 사용할 커스텀/공유 스레드 풀을 설정할 수 있게 해 줘요. 기본으로 각 컨슈머는 자기만의 단일 스레드 풀을 가져요. | | ScheduledExecutorService | | scheduler (scheduler) | camel-spring이나 camel-quartz 컴포넌트의 cron 스케줄러를 사용해요. 내장 스케줄러는 값으로 spring 또는 quartz를 쓰세요. | none | Object | | schedulerProperties (scheduler) | 커스텀 스케줄러나 Quartz, Spring 기반 스케줄러를 사용할 때 추가 프로퍼티를 설정해요. scheduler. 접두사가 붙은 다중 값 옵션이에요. | | Map | | startScheduler (scheduler) | 스케줄러를 자동으로 시작할지 여부예요. | true | boolean | | timeUnit (scheduler) |

initialDelay와 delay 옵션의 시간 단위예요.

Enum values:

  • NANOSECONDS

  • MICROSECONDS

  • MILLISECONDS

  • SECONDS

  • MINUTES

  • HOURS

  • DAYS

| MILLISECONDS | TimeUnit | | useFixedDelay (scheduler) | 고정 지연(fixed delay)을 쓸지 고정 비율(fixed rate)을 쓸지 제어해요. 자세한 내용은 JDK의 ScheduledExecutorService를 보세요. | true | boolean |

메시지 헤더 (Message Headers)

Keycloak 컴포넌트가 지원하는 메시지 헤더는 아래와 같아요:

Name Description Default Type
CamelKeycloakOperation (common) Constant: OPERATION
수행할 연산이에요.

Enum values:

  • createRealm

  • deleteRealm

  • getRealm

  • updateRealm

  • createUser

  • deleteUser

  • getUser

  • updateUser

  • listUsers

  • searchUsers

  • createRole

  • deleteRole

  • getRole

  • updateRole

  • listRoles

  • assignRoleToUser

  • removeRoleFromUser

  • getUserRoles

  • createGroup

  • deleteGroup

  • getGroup

  • updateGroup

  • listGroups

  • addUserToGroup

  • removeUserFromGroup

  • listUserGroups

  • createClient

  • deleteClient

  • getClient

  • updateClient

  • listClients

  • resetUserPassword

  • createClientRole

  • deleteClientRole

  • getClientRole

  • updateClientRole

  • listClientRoles

  • assignClientRoleToUser

  • removeClientRoleFromUser

  • listUserSessions

  • logoutUser

  • logoutAllUsers

  • revokeAccessToken

  • revokeRefreshToken

  • introspectToken

  • pushNotBefore

  • createClientScope

  • deleteClientScope

  • getClientScope

  • updateClientScope

  • listClientScopes

  • createIdentityProvider

  • deleteIdentityProvider

  • getIdentityProvider

  • updateIdentityProvider

  • listIdentityProviders

  • createResource

  • deleteResource

  • getResource

  • updateResource

  • listResources

  • createResourcePolicy

  • deleteResourcePolicy

  • getResourcePolicy

  • updateResourcePolicy

  • listResourcePolicies

  • createResourcePermission

  • deleteResourcePermission

  • getResourcePermission

  • updateResourcePermission

  • listResourcePermissions

  • evaluatePermission

  • getUserAttributes

  • setUserAttribute

  • deleteUserAttribute

  • getUserCredentials

  • deleteUserCredential

  • sendVerifyEmail

  • sendPasswordResetEmail

  • addRequiredAction

  • removeRequiredAction

  • executeActionsEmail

  • getClientSecret

  • regenerateClientSecret

  • bulkCreateUsers

  • bulkDeleteUsers

  • bulkAssignRolesToUser

  • bulkAssignRoleToUsers

  • bulkUpdateUsers

  • createOrganization

  • updateOrganization

  • deleteOrganization

  • getOrganization

  • listOrganizations

  • searchOrganizations

  • addOrganizationMember

  • removeOrganizationMember

  • listOrganizationMembers

  • linkOrganizationIdentityProvider

  • unlinkOrganizationIdentityProvider

  • listOrganizationIdentityProviders

  • addFederatedIdentity

  • removeFederatedIdentity

  • getFederatedIdentities

| | KeycloakOperations | | CamelKeycloakRealmName (common) Constant: REALM_NAME | realm 이름이에요. | | String | | CamelKeycloakUserId (common) Constant: USER_ID | 사용자 ID예요. | | String | | CamelKeycloakUsername (common) Constant: USERNAME | 사용자 이름이에요. | | String | | CamelKeycloakUserEmail (common) Constant: USER_EMAIL | 사용자 이메일이에요. | | String | | CamelKeycloakUserFirstName (common) Constant: USER_FIRST_NAME | 사용자 이름(first name)이에요. | | String | | CamelKeycloakUserLastName (common) Constant: USER_LAST_NAME | 사용자 성(last name)이에요. | | String | | CamelKeycloakRoleId (common) Constant: ROLE_ID | 역할 ID예요. | | String | | CamelKeycloakRoleName (common) Constant: ROLE_NAME | 역할 이름이에요. | | String | | CamelKeycloakRoleDescription (common) Constant: ROLE_DESCRIPTION | 역할 설명이에요. | | String | | CamelKeycloakGroupId (common) Constant: GROUP_ID | 그룹 ID예요. | | String | | CamelKeycloakGroupName (common) Constant: GROUP_NAME | 그룹 이름이에요. | | String | | CamelKeycloakClientId (common) Constant: CLIENT_ID | 클라이언트 ID예요. | | String | | CamelKeycloakClientUuid (common) Constant: CLIENT_UUID | 클라이언트 UUID예요. | | String | | CamelKeycloakUserPassword (common) Constant: USER_PASSWORD | 사용자 비밀번호예요. | | String | | CamelKeycloakPasswordTemporary (common) Constant: PASSWORD_TEMPORARY | 비밀번호가 임시(temporary)인지 여부예요. | | Boolean | | CamelKeycloakSearchQuery (common) Constant: SEARCH_QUERY | 검색 쿼리 문자열이에요. | | String | | CamelKeycloakMaxResults (common) Constant: MAX_RESULTS | 최대 결과 개수예요. | | Integer | | CamelKeycloakFirstResult (common) Constant: FIRST_RESULT | 첫 결과 인덱스예요. | | Integer | | CamelKeycloakClientScopeId (common) Constant: CLIENT_SCOPE_ID | 클라이언트 스코프 ID예요. | | String | | CamelKeycloakClientScopeName (common) Constant: CLIENT_SCOPE_NAME | 클라이언트 스코프 이름이에요. | | String | | CamelKeycloakEventType (common) Constant: EVENT_TYPE | 이벤트 타입이에요(event 또는 admin-event). | | String | | CamelKeycloakEventId (common) Constant: EVENT_ID | 이벤트 ID 또는 타임스탬프예요. | | Long | | CamelKeycloakIdpAlias (common) Constant: IDP_ALIAS | 아이덴티티 프로바이더 별칭이에요. | | String | | CamelKeycloakIdpId (common) Constant: IDP_ID | 아이덴티티 프로바이더 ID예요. | | String | | CamelKeycloakResourceId (common) Constant: RESOURCE_ID | 리소스 ID예요. | | String | | CamelKeycloakResourceName (common) Constant: RESOURCE_NAME | 리소스 이름이에요. | | String | | CamelKeycloakResourceType (common) Constant: RESOURCE_TYPE | 리소스 타입이에요. | | String | | CamelKeycloakResourceUri (common) Constant: RESOURCE_URI | 리소스 URI예요. | | String | | CamelKeycloakPolicyId (common) Constant: POLICY_ID | 정책 ID예요. | | String | | CamelKeycloakPolicyName (common) Constant: POLICY_NAME | 정책 이름이에요. | | String | | CamelKeycloakPolicyType (common) Constant: POLICY_TYPE | 정책 타입이에요. | | String | | CamelKeycloakPermissionId (common) Constant: PERMISSION_ID | 권한 ID예요. | | String | | CamelKeycloakPermissionName (common) Constant: PERMISSION_NAME | 권한 이름이에요. | | String | | CamelKeycloakScopeName (common) Constant: SCOPE_NAME | 스코프 이름이에요. | | String | | CamelKeycloakAttributeName (common) Constant: ATTRIBUTE_NAME | 사용자 속성 이름이에요. | | String | | CamelKeycloakAttributeValue (common) Constant: ATTRIBUTE_VALUE | 사용자 속성 값이에요. | | String | | CamelKeycloakCredentialId (common) Constant: CREDENTIAL_ID | 자격 증명 ID예요. | | String | | CamelKeycloakCredentialType (common) Constant: CREDENTIAL_TYPE | 자격 증명 타입이에요. | | String | | CamelKeycloakRequiredAction (common) Constant: REQUIRED_ACTION | 필수 동작(required action) 타입이에요. | | String | | CamelKeycloakActions (common) Constant: ACTIONS | 실행할 동작 목록이에요. | | List | | CamelKeycloakRedirectUri (common) Constant: REDIRECT_URI | 리다이렉트 URI예요. | | String | | CamelKeycloakLifespan (common) Constant: LIFESPAN | 수명(lifespan, 초)이에요. | | Integer | | CamelKeycloakUsers (common) Constant: USERS | 벌크 연산에 쓸 사용자 목록이에요. | | List | | CamelKeycloakUserIds (common) Constant: USER_IDS | 벌크 연산에 쓸 사용자 ID 목록이에요. | | List | | CamelKeycloakUsernames (common) Constant: USERNAMES | 벌크 연산에 쓸 사용자 이름 목록이에요. | | List | | CamelKeycloakRoleNames (common) Constant: ROLE_NAMES | 벌크 연산에 쓸 역할 이름 목록이에요. | | List | | CamelKeycloakContinueOnError (common) Constant: CONTINUE_ON_ERROR | 벌크 연산 중 에러가 나도 계속 진행할지 여부예요. | | Boolean | | CamelKeycloakBatchSize (common) Constant: BATCH_SIZE | 벌크 연산의 배치 크기예요. | | Integer | | CamelKeycloakAccessToken (common) Constant: ACCESS_TOKEN | 권한 평가에 쓸 액세스 토큰이에요. | | String | | CamelKeycloakToken (common) Constant: TOKEN | 폐기(revocation)나 인트로스펙션에 쓸 토큰이에요. | | String | | CamelKeycloakTokenTypeHint (common) Constant: TOKEN_TYPE_HINT | 폐기에 쓸 토큰 타입 힌트예요. | | String | | CamelKeycloakPermissionResourceNames (common) Constant: PERMISSION_RESOURCE_NAMES | 권한을 평가할 리소스 이름 또는 ID 목록이에요(쉼표로 구분). | | String | | CamelKeycloakPermissionScopes (common) Constant: PERMISSION_SCOPES | 권한을 평가할 스코프 목록이에요(쉼표로 구분). | | String | | CamelKeycloakSubjectToken (common) Constant: SUBJECT_TOKEN | 사용자를 대신해 권한을 평가할 때 쓸 subject 토큰이에요. | | String | | CamelKeycloakPermissionAudience (common) Constant: PERMISSION_AUDIENCE | 권한 평가의 대상(audience)이에요. | | String | | CamelKeycloakPermissionsOnly (common) Constant: PERMISSIONS_ONLY | RPT를 발급받지 않고 권한 목록만 돌려받을지 여부예요. | | Boolean | | CamelKeycloakOrganizationId (common) Constant: ORGANIZATION_ID | 조직 ID예요. | | String | | CamelKeycloakOrganizationName (common) Constant: ORGANIZATION_NAME | 조직 이름이에요. | | String | | CamelKeycloakOrganizationAlias (common) Constant: ORGANIZATION_ALIAS | 조직 별칭이에요. | | String | | CamelKeycloakOrganizationDescription (common) Constant: ORGANIZATION_DESCRIPTION | 조직 설명이에요. | | String | | CamelKeycloakOrganizationRedirectUrl (common) Constant: ORGANIZATION_REDIRECT_URL | 조직 리다이렉트 URL이에요. | | String | | CamelKeycloakOrganizationDomain (common) Constant: ORGANIZATION_DOMAIN | 조직 도메인 이름이에요. | | String | | CamelKeycloakOrganizationSearch (common) Constant: ORGANIZATION_SEARCH | 조직 검색 쿼리예요. | | String | | CamelKeycloakIdentityProvider (common) Constant: IDENTITY_PROVIDER | 페더레이티드 아이덴티티 연결에 쓸 아이덴티티 프로바이더 별칭이에요. | | String | | CamelKeycloakFederatedUserId (common) Constant: FEDERATED_USER_ID | 외부 아이덴티티 프로바이더에서의 사용자 id예요. | | String | | CamelKeycloakFederatedUsername (common) Constant: FEDERATED_USERNAME | 외부 아이덴티티 프로바이더에서의 사용자 이름이에요. | | String |

개요 (Overview)

Producer

producer는 Admin API를 통해 Keycloak에 대한 포괄적인 관리 연산을 지원해요. 사용자 관리, 역할 관리, 클라이언트 관리, 그룹 관리, 세션 관리, 토큰 관리, 아이덴티티 프로바이더, 조직(organizations), 인가 서비스, 벌크 연산이 여기에 포함돼요.

지원되는 연산 전체 목록, 설정 세부 사항, 예제는 Keycloak Producer Operations에서 확인할 수 있어요.

Consumer

consumer는 Keycloak에서 사용자 이벤트(로그인, 로그아웃, 가입)와 관리자 이벤트(리소스 생성·수정·삭제)를 폴링할 수 있게 해 줘요. 이벤트 타입, 연산 타입, 날짜 범위, 사용자, 클라이언트, IP 주소로 필터링을 지원하고, 지문(fingerprint) 기반 중복 제거도 내장돼 있어요.

설정, 이벤트 처리 패턴, 예제는 Keycloak Consumer Operations에서 확인할 수 있어요.

시큐리티 정책 (Security Policies)

시큐리티 정책은 Keycloak 액세스 토큰을 검증해서 라우트 수준 인가를 제공해요. 역할 기반·권한 기반 인가를 지원하고, 플러그형 캐시 구현과 함께 로컬 JWT 파싱과 OAuth 2.0 토큰 인트로스펙션(RFC 7662)도 지원해요.

설정, 토큰 인트로스펙션 구성 방법, 예제는 Keycloak Security Policies에서 확인할 수 있어요.

사용법 (Usage)

액세스 토큰 제공하기 (Providing Access Tokens)

시큐리티 정책은 액세스 토큰이 다음 방법 중 하나로 제공되길 기대해요:

  1. 헤더(Header): CamelKeycloakAccessToken

  2. Authorization 헤더: Authorization: Bearer <token>

  3. Exchange 프로퍼티: CamelKeycloakAccessToken

Java 전용: exchange에서 토큰 가져오기

// Using header
template.sendBodyAndHeader("direct:protected", "message",
    "CamelKeycloakAccessToken", accessToken);

// Using Authorization header
template.sendBodyAndHeader("direct:protected", "message",
    "Authorization", "Bearer " + accessToken);

라우트 예제 (Route Examples)

  • Java

  • YAML

from("direct:admin-only")
    .policy(adminPolicy)
    .transform().constant("Admin access granted")
    .to("mock:admin");

from("direct:user-or-admin")
    .policy(userPolicy)
    .transform().constant("User access granted")
    .to("mock:user");

from("rest:get:/api/documents")
    .policy(documentsPolicy)
    .to("direct:list-documents");
- route:
    from:
      uri: direct:admin-only
      steps:
        - policy:
            ref: adminPolicy
        - transform:
            constant: "Admin access granted"
        - to:
            uri: mock:admin

- route:
    from:
      uri: direct:user-or-admin
      steps:
        - policy:
            ref: userPolicy
        - transform:
            constant: "User access granted"
        - to:
            uri: mock:user

- route:
    from:
      uri: rest:get:/api/documents
      steps:
        - policy:
            ref: documentsPolicy
        - to:
            uri: direct:list-documents

페더레이티드 아이덴티티 연산 (Federated Identity Operations)

페더레이티드 아이덴티티(federated identity) 연산은 Keycloak 사용자와 외부 아이덴티티 프로바이더 계정(Google, GitHub, SAML 프로바이더 등) 사이의 연결을 관리해요. SSO 시나리오와, 마이그레이션 중에 미리 연결된 IdP 계정으로 사용자를 프로비저닝할 때 유용해요.

  • addFederatedIdentity — 사용자를 아이덴티티 프로바이더 계정에 연결해요.

  • removeFederatedIdentity — 사용자를 아이덴티티 프로바이더에서 연결 해제해요.

  • getFederatedIdentities — 사용자의 모든 아이덴티티 프로바이더 연결을 조회해요.

세 연산 모두 CamelKeycloakRealmName과 CamelKeycloakUserId가 필요해요. 추가로:

  • addFederatedIdentity는 CamelKeycloakIdentityProvider(IdP 별칭)와 CamelKeycloakFederatedUserId(프로바이더에서의 사용자 id)가 필요해요. CamelKeycloakFederatedUsername은 선택 사항인데, 넣지 않으면 외부 사용자 id가 username으로 쓰여요.

  • removeFederatedIdentity는 CamelKeycloakIdentityProvider가 필요해요.

getFederatedIdentities는 연결 목록인 List<FederatedIdentityRepresentation>을 out-message 본문으로 설정해요.

  • Java

  • YAML

from("direct:linkAccount")
    .setHeader(KeycloakConstants.REALM_NAME, constant("myrealm"))
    .setHeader(KeycloakConstants.USER_ID, constant("user-uuid"))
    .setHeader(KeycloakConstants.IDENTITY_PROVIDER, constant("google"))
    .setHeader(KeycloakConstants.FEDERATED_USER_ID, constant("google-account-id"))
    .setHeader(KeycloakConstants.FEDERATED_USERNAME, constant("jane@example.com"))
    .to("keycloak:admin?operation=addFederatedIdentity");

from("direct:listLinks")
    .setHeader(KeycloakConstants.REALM_NAME, constant("myrealm"))
    .setHeader(KeycloakConstants.USER_ID, constant("user-uuid"))
    .to("keycloak:admin?operation=getFederatedIdentities");
- route:
    from:
      uri: direct:linkAccount
      steps:
        - setHeader:
            name: CamelKeycloakRealmName
            constant: "myrealm"
        - setHeader:
            name: CamelKeycloakUserId
            constant: "user-uuid"
        - setHeader:
            name: CamelKeycloakIdentityProvider
            constant: "google"
        - setHeader:
            name: CamelKeycloakFederatedUserId
            constant: "google-account-id"
        - to:
            uri: keycloak:admin?operation=addFederatedIdentity

설정 옵션 (Configuration Options)

Name Default Description
serverUrl Keycloak 서버 URL(예: http://localhost:8080)
realm Keycloak realm 이름
clientId Keycloak 클라이언트 ID
clientSecret Keycloak 클라이언트 시크릿(client credentials 흐름용)
username 사용자 이름(resource owner password 흐름용)
password 비밀번호(resource owner password 흐름용)
requiredRoles "" 필요한 역할 목록(쉼표로 구분, 예: "admin,user,manager")
requiredPermissions "" 필요한 권한 목록(쉼표로 구분, 예: "read:documents,write:documents")
allRolesRequired true 모든 역할이 필요한지(true) 아니면 하나라도 필요한지(false) 여부
allPermissionsRequired true 모든 권한이 필요한지(true) 아니면 하나라도 필요한지(false) 여부
useResourceOwnerPasswordCredentials false resource owner password 흐름을 사용할지 여부

보안 고려 사항 (Security Considerations)

  • 프로덕션 환경에서는 항상 HTTPS를 사용해요

  • 클라이언트 시크릿은 안전하게 보관해요(환경 변수, 시크릿 관리 시스템)

  • 클라이언트 시크릿과 사용자 비밀번호를 주기적으로 교체해요

  • 역할과 권한을 부여할 때는 최소 권한 원칙을 따라요

  • 토큰 만료와 갱신 전략을 고려해요

에러 처리 (Error Handling)

컴포넌트는 다음 경우에 CamelAuthorizationException을 던져요:

  • 액세스 토큰이 없거나 유효하지 않을 때

  • 사용자에게 필요한 역할이 없을 때

  • 사용자에게 필요한 권한이 없을 때

  • Keycloak 서버에 도달할 수 없을 때

  • 토큰 검증에 실패했을 때

  • Java

  • YAML

onException(CamelAuthorizationException.class)
    .handled(true)
    .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
    .transform().constant("Access denied");
- onException:
    exception:
      - "org.apache.camel.CamelAuthorizationException"
    handled:
      constant:
        expression: "true"
    steps:
      - setHeader:
          name: "CamelHttpResponseCode"
          constant: 403
      - transform:
          constant: "Access denied"

통합 테스트 실행 (Running Integration Tests)

컴포넌트에는 실행 중인 Keycloak 인스턴스가 필요한 통합 테스트가 포함되어 있어요. 이 테스트들은 기본으로 비활성화되어 있고, 특정 시스템 프로퍼티가 주어질 때만 실행돼요.

통합 테스트는 다음 항목을 포괄적으로 검증해요: * 서로 다른 역할 요구 사항을 갖는 역할 기반 인가 * 커스텀 클레임과 스코프를 사용하는 권한 기반 인가 * JWKS 엔드포인트 연동을 통한 공개 키 검증 * 역할과 권한을 조합한 검증 * 공개 키 검증을 켜거나 끈 상태에서의 토큰 파싱 * 다양한 인증 헤더 형식(Bearer 토큰, 커스텀 헤더) * 토큰 만료와 유효성 검사 * 잘못된 토큰과 권한 부족에 대한 에러 처리

Docker로 Keycloak 띄우기 (Starting Keycloak with Docker)

1. Keycloak 컨테이너 시작

# Start Keycloak in development mode
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:latest start-dev

2. Keycloak Admin Console 접속

브라우저에서 http://localhost:8080/admin을 열고 다음으로 로그인하세요: - Username: admin - Password: admin

통합 테스트용 Keycloak 설정 (Keycloak Configuration for Integration Tests)

3. 테스트 realm 만들기

  1. Keycloak Admin Console에서 **"Add realm"**을 클릭해요

  2. realm 이름을 test-realm으로 설정해요

  3. **"Create"**를 클릭해요

4. 테스트 클라이언트 만들기

  1. test-realm에서 Clients → **"Create client"**로 이동해요

  2. 다음을 설정해요:

    • Client type: OpenID Connect

    • Client ID: test-client

    • Next → Client authentication: ON

    • Authorization: ON (고급 기능을 쓸 때 선택)

    • Next → Valid redirect URIs: *

    • **"Save"**를 클릭해요

  3. Credentials 탭으로 가서 Client Secret을 복사해요

5. 테스트 역할 만들기

  1. Realm roles → **"Create role"**로 이동해요

  2. 다음 역할들을 만들어요:

    • admin-role

    • user

    • reader

6. 테스트 사용자 만들기

다음 설정으로 테스트 사용자 세 명을 만들어요:

User 1: myuser 1. Users → **"Add user"**로 이동해요 2. 설정: - Username: myuser - Email: myuser@test.com - First name: My - Last name: User - "Create" 클릭 3. Credentials 탭 → "Set password" - Password: pippo123 - Temporary: OFF 4. Role mapping 탭 → "Assign role" - Assign role: admin-role

User 2: test-user 1. 다음으로 사용자 생성: - Username: test-user - Password: user123 (temporary: OFF) - Assign role: user

User 3: reader-user 1. 다음으로 사용자 생성: - Username: reader-user - Password: reader123 (temporary: OFF) - Assign role: reader

통합 테스트 실행하기 (Running the Integration Tests)

7. Maven으로 테스트 실행

모든 통합 테스트 실행:

# Run integration tests with required properties
mvn test -Dtest=KeycloakSecurityIT \
  -Dkeycloak.server.url=http://localhost:8080 \
  -Dkeycloak.realm=test-realm \
  -Dkeycloak.client.id=test-client \
  -Dkeycloak.client.secret=YOUR_CLIENT_SECRET

특정 테스트 카테고리만 실행:

# Test only role-based authorization
mvn test -Dtest=KeycloakSecurityIT#testKeycloakSecurityPolicyWithValidAdminToken,testKeycloakSecurityPolicyWithValidUserToken,testKeycloakSecurityPolicyUserCannotAccessAdminRoute \
  -Dkeycloak.server.url=http://localhost:8080 \
  -Dkeycloak.realm=test-realm \
  -Dkeycloak.client.id=test-client \
  -Dkeycloak.client.secret=YOUR_CLIENT_SECRET

# Test only permissions-based authorization
mvn test -Dtest=KeycloakSecurityIT#testKeycloakSecurityPolicyWithPermissions,testKeycloakSecurityPolicyWithScopeBasedPermissions,testKeycloakSecurityPolicyWithCombinedRolesAndPermissions \
  -Dkeycloak.server.url=http://localhost:8080 \
  -Dkeycloak.realm=test-realm \
  -Dkeycloak.client.id=test-client \
  -Dkeycloak.client.secret=YOUR_CLIENT_SECRET

# Test only public key verification
mvn test -Dtest=KeycloakSecurityIT#testKeycloakSecurityPolicyWithPublicKeyVerification,testParseTokenDirectlyWithPublicKey \
  -Dkeycloak.server.url=http://localhost:8080 \
  -Dkeycloak.realm=test-realm \
  -Dkeycloak.client.id=test-client \
  -Dkeycloak.client.secret=YOUR_CLIENT_SECRET

YOUR_CLIENT_SECRET은 4단계에서 발급받은 실제 client secret으로 바꾸세요.

수동 producer 테스트 실행:

KeycloakProducerIT 테스트에는 producer 연산에 대한 수동 통합 테스트가 들어 있어요. 이 테스트들은 기본으로 비활성화되어 있어서 명시적으로 활성화해야 해요:

# Run manual producer integration tests
mvn test -Dtest=KeycloakProducerIT \
  -Dmanual.keycloak.test=true \
  -Dkeycloak.server.url=http://localhost:8080 \
  -Dkeycloak.realm=master \
  -Dkeycloak.username=admin \
  -Dkeycloak.password=admin

참고 KeycloakProducerIT 테스트를 실행하려면 -Dmanual.keycloak.test=true 플래그가 필요해요. 이 플래그가 없으면 다른 Keycloak 프로퍼티를 제공했더라도 테스트가 건너뛰어져요. 자동화된 CI 환경에서 테스트가 실수로 실행되는 걸 막기 위해서예요.

8. 대안: 환경 변수 설정

# For KeycloakSecurityIT tests
export KEYCLOAK_SERVER_URL=http://localhost:8080
export KEYCLOAK_REALM=test-realm
export KEYCLOAK_CLIENT_ID=test-client
export KEYCLOAK_CLIENT_SECRET=YOUR_CLIENT_SECRET

# Run security tests
mvn test -Dtest=KeycloakSecurityIT \
  -Dkeycloak.server.url=$KEYCLOAK_SERVER_URL \
  -Dkeycloak.realm=$KEYCLOAK_REALM \
  -Dkeycloak.client.id=$KEYCLOAK_CLIENT_ID \
  -Dkeycloak.client.secret=$KEYCLOAK_CLIENT_SECRET

# For manual producer tests (KeycloakProducerIT)
export KEYCLOAK_SERVER_URL=http://localhost:8080
export KEYCLOAK_REALM=master
export KEYCLOAK_USERNAME=admin
export KEYCLOAK_PASSWORD=admin

# Run manual producer tests (requires explicit flag)
mvn test -Dtest=KeycloakProducerIT \
  -Dmanual.keycloak.test=true \
  -Dkeycloak.server.url=$KEYCLOAK_SERVER_URL \
  -Dkeycloak.realm=$KEYCLOAK_REALM \
  -Dkeycloak.username=$KEYCLOAK_USERNAME \
  -Dkeycloak.password=$KEYCLOAK_PASSWORD

문제 해결 (Troubleshooting)

테스트가 건너뛰어질 때: - KeycloakSecurityIT의 경우: 필요한 프로퍼티 네 가지가 모두 제공됐는지, Keycloak이 지정한 URL에서 실행 중인지 확인하세요. - KeycloakProducerIT의 경우: -Dmanual.keycloak.test=true가 필요한 Keycloak 프로퍼티와 함께 설정됐는지 확인하세요.

401 Unauthorized: 다음을 확인하세요: - 사용자가 존재하고 비밀번호가 올바른지 - 사용자에게 필요한 역할이 할당됐는지 - 클라이언트 자격 증명이 올바른지

Connection refused: Keycloak이 실행 중이고 지정한 URL에서 접근 가능한지 확인하세요.

Token validation errors: realm 이름과 클라이언트 설정이 정확히 일치하는지 확인하세요.

Keycloak에서 권한 설정하기 (Setting up Permissions in Keycloak)

권한 기반 인가를 위해서는 토큰에 권한을 담는 방법이 몇 가지 있어요:

옵션 1: 커스텀 클레임 매퍼 (Custom Claims Mapper)

  1. realm에서 Client Scopes → roles → Mappers → Create mapper로 이동해요

  2. 다음을 설정해요:

    • Mapper Type: User Attribute

    • Name: permissions-mapper

    • User Attribute: permissions

    • Token Claim Name: permissions

    • Claim JSON Type: JSON

    • Add to ID token: ON

    • Add to access token: ON

  3. 사용자에게 permissions 속성을 추가해요:

    • Users → 사용자 선택 → Attributes 탭으로 이동해요

    • ["read:documents", "write:documents"] 같은 값을 가진 permissions 속성을 추가해요

옵션 2: 스코프 기반 권한 (Scope-based Permissions)

  1. 클라이언트 스코프를 설정해요:

    • Client Scopes → Create client scope로 이동해요

    • Scope Name: documents

    • Protocol: openid-connect

  2. 클라이언트에 스코프를 추가해요:

    • Clients → 해당 클라이언트 → Client Scopes 탭으로 이동해요

    • 스코프를 Default 또는 Optional로 추가해요

  3. 애플리케이션 코드에서는 스코프를 권한처럼 쓸 수 있어요:

Java 전용: 프로그래매틱 방식의 시큐리티 정책 설정

KeycloakSecurityPolicy policy = new KeycloakSecurityPolicy();
policy.setRequiredPermissions("documents,users,admin");
policy.setAllPermissionsRequired(false); // ANY permission

옵션 3: Authorization Services (고급)

복잡한 권한 모델에는 Keycloak Authorization Services를 켜세요:

  1. Clients → 해당 클라이언트 → Settings → Authorization Enabled: ON으로 이동해요

  2. Authorization 탭에서 Resources, Scopes, Policies를 설정해요

  3. 클라이언트에서 Authorization을 켜요

참고: Authorization Services를 완전히 연동하려면 추가 설정이 필요하고, 위의 간단한 방법들보다 복잡해요.

더 알아보기 (Learn more)

운영 연산의 전체 목록과 요청 형식은 Keycloak Producer Operations, 이벤트 폴링은 Keycloak Consumer Operations, 토큰 검증과 권한 설정은 Keycloak Security Policies 문서에서 이어서 확인할 수 있어요. 권한 기반 인가를 준비할 때는 위의 Keycloak에서 권한 설정하기(Setting up Permissions in Keycloak) 섹션의 세 가지 옵션을 먼저 검토하고, 통합 테스트 실행 절차는 통합 테스트 실행(Running Integration Tests) 섹션을 참고하세요.