Spring Boot

[Spring Boot] Spring Security 설정 방법 (쿠키 기반 인증, 세션 관리, HTTPS, CSRF 보호)

공대생안씨 2024. 11. 8. 11:52

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로만 리다이렉트
  • 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로 리다이렉트 함!