250x250
syk531
하루
syk531
전체 방문자
오늘
어제
  • 분류 전체보기 (166)
    • 개발 (166)
      • java (11)
      • kotlin (7)
      • spring, spring boot (35)
      • Javascript (4)
      • Tyhmeleaf (2)
      • Kafka (17)
      • Docker (8)
      • Kubernetes (3)
      • Elastic Stack (4)
      • react native (3)
      • Web (4)
      • GIS (3)
      • 리눅스 (16)
      • Windows (2)
      • 네트워크 (2)
      • 안드로이드앱 (5)
      • git (2)
      • Tool (15)
      • 프로젝트 (7)
      • 백준알고리즘 (14)
      • DB (2)

인기 글

최근 글

블로그 메뉴

    공지사항

    태그

    • 티스토리챌린지
    • 뉴스앱
    • 오블완

    최근 댓글

    티스토리

    hELLO · Designed By 정상우.
    syk531

    하루

    Spring Security와 Keycloak을 활용한 OAuth2 인증·인가 구현
    개발/spring, spring boot

    Spring Security와 Keycloak을 활용한 OAuth2 인증·인가 구현

    2025. 2. 5. 11:36
    728x90
    반응형

    개념

    OAuth2 (Open Authorization 2.0) : 사용자 인증, 인가(권한 부여)를 안전하게 처리하는 표준 프로토콜

    제3자 애플리케이션이 내 계정 정보를 직접 받지 않고, 대신 안전한 Access Token을 사용하도록 하는 방식

    ex) 네이버 로그인을 이용해 카카오톡에 로그인

    -> 카카오톡이 네이버 ID/PW를 직접 알 필요 없이 OAuth2를 이용해 로그인할 수 있음

    -> 네이버가 "사용자에게 Access Token을 발급" 하는 방식

     

    OAuth2 주요 구성 요소

    Authorization Server : 인증을 처리하고 Access Token을 발급하는 서버

    Resource Server : 보호된 API를 제공하는 서버

    Access Token : 사용자가 인증되었음을 증명하는 토큰

    여기서는 각 요소는 아래와 같이 동작합니다.

    Authorization Server : Keycloak

    Resource Server : Spring boot server

    Access Token : Keycloak으로 발급받은 access token(jwt)

     

    JWT(Json Web Token) : 인증에 필요한 정보들을 Token에 담아 암호화시켜 사용하는 토큰

     

    Spring security : Spring 기반 애플리케이션에서 보안(인증, 인가)을 쉽게 적용할 수 있도록 해주는 프레임워크

    OAuth2, JWT 등을 쉽게 연동할 수 있는 기능 제공

     

    전체 흐름

    [사용자] → (인증 요청) → [Authorization Server(Keycloak)] → (Access Token(jwt) 발급)
    [사용자] → (Access Token을 포함해 API 호출) → [Resource Server(Spring boot)] → (토큰 검증 후 데이터 반환)

     

    개발 과정

    1. build.gradle

    Spring security와 OAuth2 Resource Server 라이브러리를 추가합니다.

    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")

     

    2. application.yml

    Keycloak 서버의 Realm과 발행자(issuer) URL을 지정합니다.

    issuer-uri는 해당 Realm을 가리키는 url로 {base url}/realms/{realm name} 형식입니다. 하위 경로들은 비슷한 규칙으로 생성되므로 이 url만 알면 해당 Realm을 통해서 인증/인가를 처리할 수 있습니다.

    Spring security에서는 application.yml에 아래와 같이 설정하면 Keycloak을 OAuth2 인증 서버로 기능들이 동작합니다. 

    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              # Keycloak의 issuer URL
              issuer-uri: http://keycloakurl:port/realms/yourrealm

     

    3. SecurityConfig

    @Configuration
    class SecurityConfig {
        @Bean
        fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
            http
                .authorizeHttpRequests { auth ->
                    auth//.requestMatchers("/public").permitAll() // "/public"은 누구나 접근 가능
                        .anyRequest().authenticated() // 나머지는 인증 필요
                }
                .oauth2ResourceServer { 
                	it.jwt { }
                }
                .sessionManagement { session ->
                    session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                }
                .csrf { it.disable() }
            return http.build()
        }
    }

    .authorizeHttpRequests : http 요청에 대해 권한을 설정합니다.

    .anyRequest().authenticated() : 모든 요청은 인증이 필요하게 합니다.

    .oauth2ResourceServer : Spring boot 서버를 OAuth2 리소스 서버로 사용하고 jwt 를 사용해서 리소스에 접근을 허용합니다.

    .sessionManagement : Spring security에서 세션을 어떻게 관리할지 설정합니다.

    sessionCreationPolicy : 세션 생성 정책을 설정합니다.

    (SessionCreationPolicy.STATELESS : Spring security가 세션을 생성하지도 않고 기존것을 사용하지도 않습니다.

    JWT 같은 토큰방식으로 쓸때 사용하는 설정입니다.)

    csrf (Cross site Request forgery, 사이트 간 위조 요청) : 공격자가 세션 정보를 활용하여 위조요청을 보내는 행위로 Spring security에서 default로 설정되어 있습니다. Rest api를 이용한 서버로 session 기반 인증을 사용하지 않기 때문에 disable 처리합니다.

     

    4. ApiController

    @RestController
    class ApiController {
        @GetMapping("/secured")
        fun securedEndpoint(): String {
            return "Hello from secured endpoint! (Access token validated)"
        }
    }

     

    5. api 테스트

    Keycloak Access Token을 발급 받습니다.

    curl -X POST "${token_endpoint}" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         -d "grant_type=client_credentials" \
         -d "client_id=client_id" \
         -d "client_secret=client_secret" \
         -d "scope=openid"

     

    발급된 access_token을 사용해서 api를 호출하면 정상적으로 호출되는 것을 확인할 수 있습니다.

    curl -X GET ${api url} \
         -H "Authorization: Bearer ${Access token}"

    access token이 잘못되면 인증오류(401)가 발생하는것을 확인할 수 있습니다.

    728x90
    반응형
    저작자표시 (새창열림)

    '개발 > spring, spring boot' 카테고리의 다른 글

    [Kafka] Consumer Group 재연결 시 이전 메시지 무시하는 방법  (0) 2025.02.06
    @Bean 객체 이름 설정  (0) 2024.11.19
    Spring Boot: Configuration Class 오류 해결 방법 - I/O Failure  (2) 2024.09.13
    Kotlin을 사용한 sitemap.xml 자동 생성 방법 (Spring Boot)  (1) 2024.09.05
    [Java] [Gradle] Your build is currently configured to use Java 21 and Gradle 7.6.1. 에러 수정  (0) 2024.07.17
      '개발/spring, spring boot' 카테고리의 다른 글
      • [Kafka] Consumer Group 재연결 시 이전 메시지 무시하는 방법
      • @Bean 객체 이름 설정
      • Spring Boot: Configuration Class 오류 해결 방법 - I/O Failure
      • Kotlin을 사용한 sitemap.xml 자동 생성 방법 (Spring Boot)
      syk531
      syk531
      기억을 위해 기록을.

      티스토리툴바