예시 애플리케이션의 기능
Keycloak을 통합한 애플리케이션은 다음과 같은 주요 기능을 제공합니다:
- Keycloak 로그인: 안전한 인증 메커니즘 제공.
- 사용자 이름 표시: ID Token의 사용자 정보를 활용하여 사용자 이름 표시.
- 사용자 프로필 사진 표시: ID Token에서 사용자 사진 정보(picture)를 추출하여 표시.
- ID 토큰 및 접근 토큰 발급: 인증 후 ID Token과 Access Token 제공.
- 토큰 초기화: 갱신된 토큰 정보를 즉시 반영.
- 보안 엔드포인트 호출: 백엔드의 보안 API와 통신.
엔드포인트 설명
- /public: 인증 없이 접근 가능한 공개 엔드포인트.
- /secured: 인증된 사용자만 접근 가능한 보호된 엔드포인트.
Keycloak 인증 흐름
애플리케이션 다이어그램
인증 흐름
흐름 설명
- 사용자가 로그인 시도 → Keycloak으로 리다이렉트.
- Keycloak은 사용자의 인증 정보를 확인한 후 애플리케이션으로 인증 코드 발급.
- 애플리케이션은 인증 코드를 ID 토큰과 Access Token으로 교환.
- ID 토큰을 사용해 사용자를 식별하고, Access Token을 통해 보호된 API 호출.
- 사용자 이름과 패스워드 검증 후 Keycloak 인가 코드를 애플리케이션에 전송
- 애플리케이션 인가 코드를 ID 토큰 및 접근 토큰과 교환, 애플리케이션은 ID 토큰을 확인해 사용자의 ID를 검증한다.
⭐ Keycloak을 통한 인증 위임의 장점:
- 애플리케이션은 인증 구현을 직접 처리할 필요가 없습니다.
- 인증 방식 변경 시 애플리케이션 수정 없이 Keycloak에서만 설정 변경.
프론트엔드와 백엔드 통신
요청 흐름
흐름 설명
- 공개 키 캐싱: Keycloak에서 발급한 공개 키를 메모리에 저장해 효율적으로 토큰 검증.
- 토큰 검증: 토큰의 유효성과 발급 주체(Keycloak)를 확인.
- 역할(role) 확인: 토큰에 포함된 역할 정보를 기반으로 요청 승인 여부 결정.
Login into Application: Failed
원인 1: Keycloak에 클라이언트 없음
Keycloak에 애플리케이션 클라이언트가 등록되지 않으면 다음과 같은 문제가 발생:
- 오류: "Client not found"
원인 2: 클라이언트 비활성화
- 비활성화된 클라이언트는 인증 요청을 처리할 수 없습니다.
해결: 클라이언트 생성 및 설정
- Keycloak 관리자 콘솔에서 새로운 클라이언트를 생성.
- 클라이언트 설정:
- Valid Redirect URIs: 로그인 성공 후 리다이렉션될 URI 패턴 지정 (e.g., http://localhost:8000/*).
- Web Origins: 허용된 CORS 출처 설정. http://localhost:8000사용해 유용한 출처 허용.
[Settings]
Login into Application: Success
[앞에서 생성한 Keycloak user를 사용하여 로그인]
[ID Token 확인]
{
"exp": 1731859069,
"iat": 1731858769,
"auth_time": 1731858769,
"jti": "94889f68-2192-408e-a517-11e5ae75144c",
"iss": "<http://10.77.77.41:31180/realms/jeff-realm>",
"aud": "myclient",
"sub": "a6c96222-8e0f-4049-8bd7-505ef282eb66",
"typ": "ID",
"azp": "myclient",
"nonce": "361ff040-f849-4c09-84c6-b428325562a4",
"session_state": "456337a4-a0af-4582-8b11-ba253fc935fb",
"at_hash": "A7BnyuUX4aZKdZh072z3XQ",
"acr": "1",
"sid": "456337a4-a0af-4582-8b11-ba253fc935fb",
"email_verified": false,
"name": "Jeff Han",
"preferred_username": "jeff",
"given_name": "Jeff",
"family_name": "Han",
"email": "jeff@grepp.co"
}
- iss: 토큰 발급 주체 (Keycloak 서버 URL).
- sub: 인증된 사용자의 고유 ID 값
- ID Token: ID 토큰은 인증된 사용자의 ID와 애플리케이션을 연동하기 위해 사용된다.
[Show Access Token]
{
"exp": 1731859069,
"iat": 1731858769,
"auth_time": 1731858769,
"jti": "febc8170-99fa-446d-bc4a-b3b822ad51f7",
"iss": "<http://10.77.77.41:31180/realms/jeff-realm>",
"aud": "account",
"sub": "a6c96222-8e0f-4049-8bd7-505ef282eb66",
"typ": "Bearer",
"azp": "myclient",
"nonce": "361ff040-f849-4c09-84c6-b428325562a4",
"session_state": "456337a4-a0af-4582-8b11-ba253fc935fb",
"acr": "1",
"allowed-origins": [
"<http://localhost:8000>"
],
"realm_access": {
"roles": [
"jeff-global-role",
"offline_access",
"default-roles-jeff-realm",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid email profile",
"sid": "456337a4-a0af-4582-8b11-ba253fc935fb",
"email_verified": false,
"name": "Jeff Han",
"preferred_username": "jeff",
"given_name": "Jeff",
"family_name": "Han",
"email": "jeff@grepp.co"
}
- allowed-origins: 애플리케이션에 허용된 웹 출처 리스트. CORS 요청이 있는 경우 백엔드 서비스에서 CORS 요청 승인 여부를 결정하기 위해 해당 필드를 사용
- realm_access: 글로벌 역할 리스트. 사용자에게 부여된 역할과 클라이언트가 접근할 수 있는 역할 간의 교차점
- resource_access: 클라이어트의 역할 리스트
- scope: 범위를 사용해 토큰에 포함할 필드를 결정하고, 백엔드에서 토큰이 접근할 수 있는 API를 결정할 수 있음.
사용자 정의 콘텐츠
{
"exp": 1732023472,
"iat": 1732023172,
"auth_time": 1732022832,
"jti": "eadf55fa-3df7-4979-85fa-0d74ba68d437",
"iss": "",
"aud": "myclient",
"sub": "a6c96222-8e0f-4049-8bd7-505ef282eb66",
"typ": "ID",
"azp": "myclient",
"nonce": "3c3da935-330f-4b19-8317-f51cb8089dfc",
"session_state": "fad12676-48bf-4f22-9da6-ba3fff1f030f",
"at_hash": "sY3nB8-nKr9N5qYEVe27XQ",
"acr": "0",
"sid": "fad12676-48bf-4f22-9da6-ba3fff1f030f",
"email_verified": false,
"name": "Jeff Han",
"preferred_username": "jeff",
"given_name": "Jeff",
"family_name": "Han",
"picture": "<https://avatars.githubusercontent.com/u/39541657?v=4>",
"email": "jeff@grepp.co"
}
ID Token에서 picture 값이 추가된걸 확인할 수 있다.
주요 구현
사용자 프로필 사진 표시
ID 토큰의 picture 필드를 활용하여 사용자 사진 표시.
const userProfile = JSON.parse(idToken);
document.getElementById('profile-pic').src = userProfile.picture;
결론
Keycloak을 사용하면 인증 및 권한 관리를 간소화하고 보안을 강화할 수 있습니다. 특히 ID 토큰과 Access 토큰의 활용을 통해 사용자 데이터와 API 보호를 쉽게 구현할 수 있습니다.
'DevOps > Keycloak' 카테고리의 다른 글
[Keycloak]OIDC를 활용한 사용자 인증 및 로그아웃 (0) | 2025.01.19 |
---|---|
[Keycloak]Install keycloak with helm charts (0) | 2025.01.19 |
[Keycloak]개요 (0) | 2025.01.19 |
[Keycloak]OAuth, OpenID Connect, SAML, Zero Trust 개념 (0) | 2025.01.12 |