1. SecurityConfig
package oauth.core.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import oauth.core.filter.CustomLoginFilter;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final AuthenticationConfiguration authenticationConfiguration;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
CustomLoginFilter customLoginFilter = new CustomLoginFilter(authenticationManager);
customLoginFilter.setFilterProcessesUrl("/api/login");
http
.securityMatcher("/api/**")
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authz -> authz
.requestMatchers("/api/login").permitAll()
.anyRequest().authenticated()
)
.addFilterAt(customLoginFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
📌 SecurityConfig 추가 정리
securityMatcher("/api/**") : " /api/** "로 시작하는 요청에 대해 필터 체인이 작동하도록 제한
csrf(AbstractHttpConfigurer::disable) : CSRF 비활성화
formLogin(AbstractHttpConfigurer::disable) : 폼 로그인 비활성화
requestMatchers("/api/login").permitAll() : " /api/login "로 시작하는 요청만 인증 없이 접근 허용
anyRequest.authenticated() : 정의된 요청 경로 이외의 모든 요청은 인증된 사용자만 접근 가능
customLoginFilter.setFilterProcessesUrl("/api/login") : 커스텀 필터에 거치게 할 url 등록
addFilterAt(customLoginFilter, UsernamePasswordAuthenticationFilter.class) : 해당 필터를 커스텀으로 대체함
2. CustomLoginFilter
package oauth.core.filter;
import java.io.IOException;
import java.util.Map;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class CustomLoginFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
String username = obtainUsername(request);
String password = obtainPassword(request);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
return authenticationManager.authenticate(authRequest);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authentication) throws JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
response.setContentType("application/json");
response.getWriter().write(objectMapper
.writeValueAsString(Map.of(
"message",
"Authentication successful",
"user",
authentication.getPrincipal()
)));
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(objectMapper
.writeValueAsString(Map.of(
"message",
"Authentication failed",
"error",
failed.getMessage()
)));
}
}
📌 CustomLoginFilter 추가 정리
attemptAuthentication() : 사용자 인증 처리 부분
successfulAuthentication() : 인증 성공시 처리되는 부분
unsuccessfulAuthentication() : 인증 실패시 처리되는 부분
obtainUsername() : 요청에서 username으로 오는 파라미터를 가져옴
obtainPassword() : 요청에서 password으로 오는 파라미터를 가져옴
'Spring' 카테고리의 다른 글
[Spring] Oauth 연동 - Oauth2 로그인 기능 구현하기 (0) | 2025.01.22 |
---|---|
[Spring] Oauth 연동 - JWT 로그인 기능 구현하기 (1) | 2025.01.21 |
[Spring] Oauth 연동 - 폼 로그인 기능 구현하기 (3) | 2025.01.17 |
[Spring] Oauth 연동 - Security6.x 정리 (0) | 2025.01.15 |
[Spring] 자주 보는 어노테이션 정리 (1) | 2022.03.04 |