반응형
Spring Security와 전자정부프레임워크를 활용하여 OAuth 2.0의 커스텀 인증 필터를 구현하는 방법을 학습합니다. 이 과정은 사용자 인증을 맞춤화하고, Access Token을 기반으로 API 요청을 처리하는 데 유용합니다.
1. 커스텀 인증 필터란?
Spring Security의 **필터(Filter)**는 요청(Request)이 애플리케이션에 도달하기 전에 인증 및 권한 부여를 처리하는 중요한 역할을 합니다.
- 커스텀 인증 필터는 기본 인증 필터를 확장하여 요구사항에 맞는 인증 로직을 추가로 구현할 수 있습니다.
- 이 필터를 통해 Access Token을 검증하거나 사용자 정보를 로드할 수 있습니다.
2. 커스텀 인증 필터 설계
2-1. 요구사항 정의
- 모든 요청에서 Authorization 헤더에 포함된 Access Token을 확인합니다.
- Access Token의 유효성을 검증하고, 유효한 경우 사용자 정보를 SecurityContext에 저장합니다.
2-2. 필터 구현 개요
- GenericFilterBean 또는 OncePerRequestFilter를 확장합니다.
- doFilter() 메서드를 오버라이드하여 토큰 검증 로직을 추가합니다.
- Spring Security의 FilterChain에 필터를 등록합니다.
3. 커스텀 인증 필터 구현
3-1. 필터 클래스 작성
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFilter extends OncePerRequestFilter {
private final TokenValidationService tokenValidationService;
private final UserDetailsService userDetailsService;
public CustomAuthenticationFilter(TokenValidationService tokenValidationService, UserDetailsService userDetailsService) {
this.tokenValidationService = tokenValidationService;
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
if (tokenValidationService.validateAccessToken(token)) {
String username = tokenValidationService.extractUsername(token);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
CustomAuthenticationToken authentication = new CustomAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
}
3-2. TokenValidationService 클래스 구현
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.stereotype.Service;
@Service
public class TokenValidationService {
private static final String SECRET_KEY = "mysecretkey";
public boolean validateAccessToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
public String extractUsername(String token) {
Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
return claims.getSubject();
}
}
3-3. Spring Security 설정
커스텀 필터를 Spring Security의 필터 체인에 추가합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
private final CustomAuthenticationFilter customAuthenticationFilter;
public SecurityConfig(CustomAuthenticationFilter customAuthenticationFilter) {
this.customAuthenticationFilter = customAuthenticationFilter;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(customAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
4. 테스트
- API 호출 테스트
- Authorization 헤더 없이 요청: 401 Unauthorized 반환.
- 올바른 Access Token 포함: 요청 성공 및 데이터 반환.
- 로그 테스트
- Access Token이 만료된 경우, 로그에 오류 메시지를 출력합니다.
- 유효한 사용자 확인
- Access Token에서 추출된 사용자 정보가 SecurityContext에 저장되는지 확인합니다.
5. 마무리
이번 학습에서는 커스텀 인증 필터를 설계하고 구현했습니다. 이 필터는 Spring Security의 인증 과정을 확장하여 Access Token 검증과 사용자 인증 로직을 맞춤화할 수 있습니다.
다음에서는 다중 인증 방식 (JWT, OAuth 2.0)의 통합 구현을 학습합니다.
반응형
'개발 > 전자정부프레임워크' 카테고리의 다른 글
전자정부프레임워크에서 인증 로그 관리 구현 (0) | 2024.12.26 |
---|---|
다중 인증 방식 통합 구현 (JWT와 OAuth 2.0) (0) | 2024.12.26 |
Refresh Token 전략과 로그아웃 구현 (1) | 2024.12.26 |
OAuth 2.0 기반 API 요청 및 Access Token 검증 (0) | 2024.12.26 |
OAuth 2.0을 이용한 소셜 로그인 구현 (0) | 2024.12.26 |