개념
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)가 발생하는것을 확인할 수 있습니다.
'개발 > 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 |