1. Spring Security 환경 설정
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
);
http
.formLogin((auth) -> auth
.loginPage("/login")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/", true)
.usernameParameter("loginId")
.passwordParameter("password")
.permitAll()
.successHandler(new CustomAuthenticationSuccessHandler())
.failureHandler(new CustomAuthenticationFailureHandler())
);
http
.logout((auth) -> auth
.logoutUrl("/logout")
.permitAll()
);
return http.build();
}
}
- authorizeHttpRequests() : Http 요청에 대한 접근 제한 설정 (HttpServletRequest 활용하여 특정 URL 패턴에 대한 인증 및 권한 부여 정의)
- requestMatchers() : 특정 경로 지정
- permitAll() : 모든 사용자에게 접근 권한 허용
- anyRequest().authenticated() : 인증되지 않은 모든 요청을 차단하고 인증 요구
- formLogin() : 폼 기반 로그인을 사용하도록 설정
- loginPage() : 사용자 정의 로그인 페이지 URL 설정
- loginProcessingUrl() : 로그인 요청을 처리할 URL 지정, 사용자가 로그인 양식을 제출할 때 이 URL로 요청 전송됨
- defaultSuccessUrl(”/”, true) : 로그인 성공 후 리다이렉트 될 기본 URL 설정
- 2번째 인자 : 사용자가 이전에 접근했던 URL로 리다이렉트 여부
- true : 이전 URL로 리다이렉트
- false : 기본 URL로만 리다이렉트
- 2번째 인자 : 사용자가 이전에 접근했던 URL로 리다이렉트 여부
- usernameParameter() : 로그인 시 사용할 사용자 이름의 파라미터 설정
- 기본값 : username
- passwordParameter() : 로그인 시 사용할 비밀번호의 파라미터 설정
- 기본값 : password
- successHandler() : 로그인 성공 후의 동작을 정의하는 커스텀 성공 핸들러 설정
- failureHandler() : 로그인 실패 시의 동작을 정의하는 커스텀 실패 핸들러 설정
2. Spring Security 쿠키 기반 인증 설정 (자동 로그인 관련)
// Remember-Me : 자동로그인
http
.rememberMe(rememberMe -> rememberMe
.key("anchangmin")
.rememberMeParameter("remember-me")
.tokenValiditySeconds(60*60*24*30)
.authenticationSuccessHandler(new CustomAuthenticationSuccessHandler())
);
- rememberMe() : 사용자가 웹 사이트에 다시 방문할 때 로그인 유지 (Remember-Me)
- key() : 고유 키 설정
- 고유 키 : 클라이언트가 인증된 후에 생성되는 토큰을 암호화하는데 사용됨!
- rememberMeParameter() : Remember-Me (자동로그인) 체크박스의 파라미터 이름 설정, 사용자가 이 체크박스를 선택하면 이 이름으로 파라미터 전송됨
- 기본값 : “remember-me”
- tokenValiditySeconds() : 토큰 유효 시간 설정 (초 단위), 이 기간 동안 사용자는 자동 로그인 상태 유지 가능
3. Spring Security 세션 관리 설정
http
.sessionManagement((auth) -> auth
.sessionFixation().none()
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
.expiredUrl("/session-expired-url")
);
- sessionManagement() : 세션 관리 설정
- sessionFixation().none() : 세션 고정 공격에 대해 아무 조치 x
- 보통 migrateSession() 이나 newSession() 을 사용하는 것이 보안상 권장됨
- maximumSessions() : 동일한 사용자 계정으로 동시에 허용되는 최대 세션 수 설정 (여기서는 1로 설정 ⇒ 다른 곳에서 로그인하면 이전 세션 종료됨)
- maxSessionsPreventsLogin() : 최대 세션 수에 도달 후 새로운 로그인 허용 여부 설정
- false : 새로운 세션 생성 허용 + 이전 세션 만료
- true : 새로운 로그인 시도 차단됨
- expiredUrl() : 세션 만료되었을 때 사용자가 리다이렉트될 URL 설정
4. Spring Security CSRF 설정
http
.csrf(csrf -> csrf
.requireCsrfProtectionMatcher(request -> {
// CSRF 보호가 필요한 요청을 정의 (예: POST 요청만)
return request.getMethod().equals("POST");
})
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // CSRF 토큰 저장소 설정
);
- csrf() : CSRF 설정 시작
- Cross-Site Request Forgery 보호 활성화
- requireCsrfProtectionMathcer() : CSRF 보호가 필요한 요청을 정의하는 커스텀 매쳐 설정
- ex) POST 요청에 대해서만 CSRF 보호 적용 등
- csrfTokenRepository() : CSRF 토큰 저장 방법 설정
- CookieCsrfTokenRepository : 쿠키 기반 CSRF 토큰 저장소 사용
- withHttpOnlyFalse() : 생성된 쿠키의 HttpOnly 속성을 false 로 지정 ( = 자바스크립트에서 CSRF 토큰에 접근 가능함)
📌 클라이언트에서 CSRF 토큰 사용
⇒ 서버로부터 받은 CSRF 토큰을 HTML 폼에 포함시켜야 함!
- 예시 코드
<form action="/your-action" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <!-- 추가 입력 필드 --> <button type="submit">제출</button> </form>
5. Spring Security HTTPS 설정
http
.requiresChannel(https -> https
.anyRequest()
.requiresSecure() // 모든 요청을 HTTPS로 요구)
);
- requiresChannel() : 요청의 전송 채널 (HTTP or HTTPS) 에 대한 요구 사항 설정
- 클라이언트가 특정 요청을 보내는 방식 (HTTP or HTTPS) 지정 가능
- requiresSecure() : 해당 요청이 HTTPS 를 통해서만 처리되어야 함 설정
- HTTP 프로토콜로 요청을 보내면 Spring Security가 차단하고 HTTPS로 리다이렉트 함!