Spring Boot으로 OAuth2 클라이언트 구현(권한 코드 흐름)
Spring Boot에서 Authorization Code 흐름을 이용한 OAuth2 클라이언트 구현과 설정 예제, 동작 원리와 주의사항을 초보자도 이해하기 쉽게 정리한 설명서. 설정방법
목차
개요
OAuth2의 Authorization Code 흐름은 사용자 인증과 권한 위임에서 가장 안전하게 권장되는 방식이다. 서버 사이드 애플리케이션이 인증 서버와 상호작용해 액세스 토큰을 안전하게 발급받는 구조다. 이 글은 Spring Boot에서 OAuth2 클라이언트를 설정하고 동작 원리를 이해하기 쉬운 예제로 설명한다.
권한 코드 흐름 개념
흐름 요약
- 사용자는 클라이언트(애플리케이션)에서 인증 요청을 시작한다.
- 인증 서버는 사용자 인증 후 권한 코드를 클라이언트로 전달한다.
- 클라이언트는 권한 코드와 클라이언트 자격 증명을 사용해 인증 서버에 액세스 토큰을 요청한다.
- 인증 서버는 액세스 토큰(및 선택적으로 리프레시 토큰)을 발급한다.
이 흐름은 클라이언트가 액세스 토큰을 직접 브라우저에서 받지 않으므로 토큰 유출 위험이 낮다.
프로젝트 준비
필수 의존성
Spring Boot에서 OAuth2 클라이언트를 사용하려면 Spring Security의 OAuth2 클라이언트 모듈이 필요하다. Gradle과 Maven 예제는 다음과 같다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
애플리케이션 설정 예제
인증 서버 정보와 클라이언트 정보를 application.yml에 설정한다. 여기서는 일반적인 OAuth2 제공자 구성을 예시로 둔다.
spring:
security:
oauth2:
client:
registration:
my-provider:
client-id: my-client-id
client-secret: my-client-secret
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: openid,profile,email
provider:
my-provider:
authorization-uri: https://auth.example.com/oauth2/authorize
token-uri: https://auth.example.com/oauth2/token
user-info-uri: https://auth.example.com/userinfo
user-name-attribute: sub
Spring Security 설정
기본적으로 Spring Security는 OAuth2 클라이언트 동작을 많이 자동화한다. 필요시 커스터마이징하는 방법을 간단히 소개한다.
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(org.springframework.security.config.annotation.web.builders.HttpSecurity http) throws Exception {
http
.authorizeRequests(a -> a
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2Login();
return http.build();
}
}
위 설정으로 사용자가 보호된 리소스에 접근하면 자동으로 인증 서버의 로그인 페이지로 리다이렉트된다.
컨트롤러에서 사용자 정보 사용
로그인 후 Principal 또는 OAuth2AuthenticationToken으로 사용자 정보를 읽는다. 간단한 예제를 보자.
@Controller
public class UserController {
@GetMapping("/")
public String index(org.springframework.security.core.annotation.AuthenticationPrincipal org.springframework.security.oauth2.core.user.OAuth2User principal, Model model) {
model.addAttribute("name", principal.getAttribute("name"));
return "index";
}
}
동작 확인과 주요 포인트
- redirect-uri와 등록된 리디렉션이 일치하는지 확인한다.
- client-secret은 서버 사이드에서 안전하게 관리해야 한다.
- scope는 최소 권한 원칙을 지켜 필요한 권한만 요청한다.
- 인증 서버의 user-info 엔드포인트 응답 구조에 따라 user-name-attribute를 조정한다.
리프레시 토큰과 토큰 갱신
Authorization Code 흐름에서는 리프레시 토큰을 함께 발급받을 수 있다. Spring Security는 기본적으로 토큰 관리를 제공하지만, 세부 제어가 필요하면 OAuth2AuthorizedClientService를 사용해 직접 저장하고 갱신 로직을 구현할 수 있다.
실무에서의 고려사항
- HTTPS 사용은 필수다. 토큰과 자격 증명을 안전하게 전송해야 한다.
- 로그에 민감한 정보를 기록하지 않는다. client-secret, 토큰 값 등은 제외한다.
- 세션과 CSRF 처리 방식을 인증 서버와 클라이언트 요구사항에 맞춰 조정한다.
문제 해결 팁
- redirect-uri 불일치: 등록값과 애플리케이션 설정을 재확인.
- invalid_client: client-id 또는 client-secret 오류 가능성.
- scope 관련 권한 거부: 인증 서버에서 클라이언트 권한 허용 여부 확인.
마무리
정리하면 Spring Boot는 OAuth2 Authorization Code 흐름을 비교적 간단히 구성할 수 있다. application.yml에 제공자 정보를 등록하고, Spring Security 설정을 활성화하면 인증 서버와 연동해 안전하게 토큰을 주고받는다. 예제를 따라 설정값을 확인하면 초보자도 흐름을 이해하고 적용하는 데 도움이 된다.