KEYCLOAK - 1.(인증)_개념잡기

킹콩(King Kong)·2025년 4월 25일

KEYCLOAK 사용법

목록 보기
1/4

Keycloak 개요

  • Keycloak은 모든 Application 공통 기능인 <인증>과 <인가>를 지원하는 오픈 소스이다.
  • Keycloak 적용만으로 아래의 기능을 모두 수행 할 수 있다는 얘기, 개발 없이 말이다~!

인증(Authentication)

  • 로그인 : 사용자 식별(Identity)
  • 회원가입
  • 이메일 본인확인 (휴대폰X)
  • 2차 인증 (2FA) : OTP
  • 소셜 로그인
  • 다국어 지원
  • SSO (Single Sing On)

인가(Authorization)

  • 자원 관리 : REAT API
  • 범위 관리 : READ / WRITE (Action)
  • 정책 관리
    • ROLE 기반 정책
    • GROUP 기반 정책
    • TIME 기반 정책
    • 사용자 기반 정책
  • 권한 제어 : 자원에 대한 접근 통제(허용/불가) 관리

(참고) 사용자 vs 권한 간 개념 ERD

  • <사용자>는 할당 받은 <권한>에 따라 허용되는 <자원>만 접근할 수 있다.
  • Kecloak은 이 3개 Object 즉, <사용자> <권한> <자원>의 관계를 정의하고 관리할 수 있도록 지원하는 오픈 소스이다.

▶Spring Security vs Keycloak

  • Aplication의 접근통제를 위해 Springframework 환경에서는 Spring Security를 많이 사용한다.
  • 이에 Keycloak과 Spring Security와의 차이점과 비슷한 점을 먼저 비교해 본다.

1. Dependency 적용

  • Keycloak을 적용하면 Spring Security 를 적용했을 때 처럼 Application에 대한 모든 접근이 Keycloak에 의해 통제된다.

[ Spring Security dependency 적용 시 pom.xml 샘플 ]

<!-- Spring Security dependency add -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

[ KEYCLOAK dependency 적용 시 pom.xml 샘플 ]

<!-- keycloak dependency add -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

2. Spring Security dependency 적용 시

  • Spring Security를 적용하면 Application에 대한 전체 접근이 통제 되며 아래와 같이 Spring Security에서 지원하는 기본 로그인 화면으로 이동한다.
  • 이때 ID는 'user', Password는 '기동시 console log'에 제시되는 비밀번호로 로그인 할 수 있다.
    • 사용자가 지정한 Member 테이블에서 ID/PW를 체크하게 수정할 수 도 있다.

3. Keycloak dependency 적용 시

  • Keycloak을 적용하면 Application 접근시 Keycloak 공통 로그인 화면으로 Redirect 된다.

  • Keycloak의 <공통 로그인 화면>을 통해서 아래의 기능이 기본으로 제공된다.

    • 로그인 : 사용자 식별(Identity)
    • 회원가입하기
    • 이메일 본인확인 (휴대폰은 지원 안함)
    • 비밀번호 찾기
    • 2차 인증(2FA) : OTP
    • 다국어 지원
    • SSO (Single Sign On)
  • 아래는 기본으로 지원하는 화면을 캡쳐한 내용이다.

4. SecurityContextHolder 비교 (차이점)

  • 이러한 Security 관련한 앞의 두 방식을 간단히 비교해 보았을 때,
  • Spring Security vs Keycloak 인증 시 Context Holder의 세션 정보가 다르게 구성된다.
구분SecurityContextHolder.Authentication
Spring SecurityAuthentication.getPricipan()에 UserDetails 정보 저장
KeycloakAuthentication.getPricipal()에 OidcUser 정보 저장

5. Authentication.getPricipal() - UserDetails

  • 사용자가 Spring Security 적용시 로그인 하면 아래와 같이 지정한 Member 테이블의 속성으로 세션이 구성된다.

6. Authentication.getPricipal() - OidcUser

  • Keycloak 적용시 로그인 하면 Keycloak이 발급한 Token 정보들로 세션이 구성된다.

7. SecurityContextHolder 비교

  • Spring Security vs Keycloak 인증시 Context Holder의 세션 정보가 다르게 구성된다.
구분UserDetails 기반Keycloak(OIDC) 기반
Principal TypeUserDetailsOidcUser(또는 OAuth2User)
Authentication TypeUsernamePasswordAuthenticationTokenOAuth2AuthenticationToken
인증처리 방식Form 로그인Redirect-based OAuth2/OIDC
사용자 정보 로딩UserDetailsService 구현체에서 직접 로딩ID Token 및 UserInfo Endpoint 에서 자동 맵핑
Customizing PointUserDetailsServiceOAuth2UserService, OidcUserService

▶ Keycloak SSO

1. Keycloak SSO 개요

  • Keycloak에서 SSO 구현은 Realm 을 통해서 자동으로 구현된다.

    [ 용어 정의 ]

    • Realm은 '영역', '범위'라는 뜻으로 Client들의 집합이다.
    • Client란, Application 또는 쉽게 Web Site라고 생각하면 된다.
      즉, Keycloak이 IdP 서버가 되고, Application은 ID 인증을 요청하는 Client이다.

2. Keycloak SSO 특징

  • 같은 Realm에 속하는 Client는 같은 사용자(User) 정보를 공유한다.
  • 즉, 같은 영역(Realm)의 Application (Web Site)은 같은 사용자들이 한번의 로그인으로 타 Site에 자유롭게 접근할 수 있다. (Single Sign On)
  • 같은 Realm에 있는 Application(Client)는 같은 로그인 정책, 같은 인증 정책을 따른다. (세부적으로 미세 조정은 가능)

3. Keycloak SSO 개념

  • 예를 들어 A site에 Keycloak이 적용 되었으면 A site 접근시 Keycloak 공통 로그인 화면으로 Redirect 된다.
  • 이후 A Site에 로그인 한 사용자는 B site, C site에 로그인 없이 접근 할 수 있다. (Single Sign On 동작)
  • 이러한 Keycloak SSO는 KEYCLOAK_SESSION과 KEYCLOAK_IDENTITY 라는 Cookie에 의해 동작한다.

4. Keycloak SSO - Logout

  • 이렇게 Keycloak을 통해서 로그인 한 사용자는 A,B,C site 아무곳에서나 로그아웃(Logout)을 수행하면 전체 Site에 대해 로그아웃(Logout)이 수행된다.

  • 그것은 사용자가 Logout을 호출할 때, Application은 자신의 SecurityContextHolder 정보를 삭제한다. 이후 Keycloak 세션을 삭제하고, 로컬PC(브라우저)의 Cookie를 삭제해야 전체 세션이 삭제되면서 Logout이 완성된다.

    • Keycloak 세션을 삭제하기 위해서 Application은 Keycloak Logout Endpoint를 호출한다. Keycloak Endpoint가 호출되면 하나의 KEYCLOAK_SESSION에 A,B,C site가 SSO 로 묶여있기 때문에 이 KEYCLOAK_SESSION이 삭제 되면서 모든 site에 대한 로그아웃이 수행된다.
  • 간단 코드 참조 (Logout Endpoint 호출)

@Component
public class KeycloakLogoutHandler implements LogoutHandler {

    @Value("${spring.security.oauth2.client.provider.keycloak.issuer-uri}")
    private String KEYCLOAK_URL = "";
    @Value("${appl.url}")
    private String APPL_URL = "";

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        //STEP-1 :: Spring session delete...
        if( authentication !=null && authentication.getDetails() != null ) {
            request.getSession().invalidate();
            SecurityContextHolder.clearContext();
            
            //STEP-2 :: Keycloak Session delete...
            try {
                String keycloakLogoutUrl = this.KEYCLOAK_URL + "/protocol/openid-connect/logout?post_logout_redirect_uri=" + this.APPL_URL + "&id_token_hint=" + getIdToken(authentication);
                response.sendRedirect(keycloakLogoutUrl);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private String getIdToken(Authentication authentication) {
        if( authentication instanceof OAuth2AuthenticationToken ) {
            OAuth2AuthenticationToken authToken = (OAuth2AuthenticationToken) authentication;
            OidcUser oidcUser = (OidcUser) authentication.getPrincipal();
            return oidcUser.getIdToken().getTokenValue();
        }
        return null;
    }
}
profile
IT를 쉽게 이해해 보아요~😄

0개의 댓글