본문 바로가기

SPRING

SPRING :: Security 로그인 구현 02 SecurityConfig

 

 

Spring Security (Form-Based Authentication)

가장 기본적인 자체 로그인 서비스 구현 실습

 

02. SpringSecurityConfiguration class 작성

 

 

1. Security 세부 설정 Configuration

 - 전체 코드 (화면은 리액트로 구성하기 때문에 cors를 3000 포트로 설정)

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SpringSecurityConfig {
	
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
		http
			.cors(cors -> cors
					.configurationSource(corsConfigurationSource())
			)
			.authorizeHttpRequests(authorize -> authorize
					.requestMatchers("/api/admin/**").hasRole("ADMIN")
					.requestMatchers("/api/**").authenticated()
					.anyRequest().permitAll()
					)
			.formLogin(formLogin -> formLogin
					.loginPage("/securelogin")
					.loginProcessingUrl("/loginProcess")
					.usernameParameter("id")
					.passwordParameter("password")
					.defaultSuccessUrl("/loginOk", true)
					)
			.logout(logout -> logout
					.logoutUrl("/logout")
					.logoutSuccessUrl("/logoutOk")
					.invalidateHttpSession(true)
					.deleteCookies("JSESSIONID")
					)
			.sessionManagement(session -> session
					.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
					.maximumSessions(1)
					.maxSessionsPreventsLogin(false)
					.sessionRegistry(sessionRegistry())
					);
		http.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class);
		return http.build();
			
	}
	
	@Bean
	public CorsFilter corsFilter() {
		return new CorsFilter(corsConfigurationSource());
	}

	@Bean
	public CorsConfigurationSource corsConfigurationSource() {
		CorsConfiguration config = new CorsConfiguration();
		config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
		config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
		config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
		config.setAllowCredentials(true);
		
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", config);
		
		return source;
	}
	
	@Bean
	public SessionRegistry sessionRegistry() {
		return new SessionRegistryImpl();
	}
	
	@Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }
	

}

 

 

 

상세설명

1) 어노테이션

@Configuration
@EnableWebSecurity
@EnableMethodSecurity

 

@Configuration: 이 클래스가 Spring의 설정 클래스임을 나타낸다. Spring에서 빈(Bean)을 등록하고, 설정을 적용할 수 있도록 한다.
@EnableWebSecurity: Spring Security의 웹 보안 지원을 활성화한다. 이 애노테이션을 사용하면 웹 애플리케이션의 보안 구성을 할 수 있다.
@EnableMethodSecurity: Spring Security에서 메서드 수준의 보안 처리를 활성화. 특정 메서드에 대한 접근 권한을 설정할 수 있다.

 

 

2) SecurityFilterChain 빈 설정

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{

SecurityFilterChain: Spring Security의 필터 체인을 정의. 필터 체인은 HTTP 요청을 가로채고, 보안 규칙에 따라 요청을 처리한다.
HttpSecurity: 웹 기반 보안 구성을 위한 객체로, 다양한 보안 옵션을 설정할 수 있다.

 

 

3) CORS 설정

.http
	.cors(cors -> cors
			.configurationSource(corsConfigurationSource())
	)

cors(): CORS(Cross-Origin Resource Sharing) 설정 정의. 서로 다른 출처에서 오는 HTTP 요청을 허용하는 규칙을 설정.
configurationSource(corsConfigurationSource()): corsConfigurationSource() 메서드에서 정의된 CORS 설정을 적용 (하단 기재)

 

 

4) 권한 기반 요청 허용

.authorizeHttpRequests(authorize -> authorize
		.requestMatchers("/api/admin/**").hasRole("ADMIN")
		.requestMatchers("/api/**").authenticated()
		.anyRequest().permitAll()
	)

authorizeHttpRequests(): HTTP 요청에 대한 접근 권한을 설정
requestMatchers("/api/admin/**").hasRole("ROLE_ADMIN"): /api/admin/로 시작하는 모든 요청은 "ROLE_ADMIN" 권한을 가진 사용자만 접근할 수 있다.
requestMatchers("/api/**").authenticated(): /api/로 시작하는 모든 요청은 인증된 사용자만 접근할 수 있다.
anyRequest().permitAll(): 위에서 설정한 URL 패턴을 제외한 모든 요청은 누구나 접근할 수 있도록 허용.

 

 

5) 로그인 설정

.formLogin(formLogin -> formLogin
		.loginPage("/securelogin")
		.usernameParameter("id")
		.passwordParameter("password")
		.defaultSuccessUrl("/loginOk", true)
	)

formLogin(): 기본적인 폼 기반 로그인 설정을 활성화.
loginPage("/securelogin"): 사용자가 로그인하지 않은 상태에서 보호된 리소스에 접근하려고 할 때, 리다이렉트할 로그인 페이지의 URL을 설정.
usernameParameter("id"): 로그인 폼에서 사용자 이름 필드의 이름을 "id"로 설정.
passwordParameter("password"): 로그인 폼에서 비밀번호 필드의 이름을 "password"로 설정.
defaultSuccessUrl("/loginOk", true): 로그인 성공 후 사용자가 리다이렉트될 URL을 설정. true는 항상 이 URL로 리다이렉트될 것을 의미.

 

 

6) 로그아웃 설정

.logout(logout -> logout
		.logoutUrl("/logout")
		.logoutSuccessUrl("/logoutOk")
		.invalidateHttpSession(true)
		.deleteCookies("JSESSIONID")
	)

logout(): 로그아웃 설정을 활성화.
logoutUrl("/logout"): 사용자가 로그아웃 요청을 보낼 URL을 설정.
logoutSuccessUrl("/logoutOk"): 로그아웃 성공 후 리다이렉트될 URL을 설정.
invalidateHttpSession(true): 로그아웃 시 HTTP 세션을 무효화하여 세션에 저장된 모든 데이터를 제거.
deleteCookies("JSESSIONID"): 로그아웃 시 JSESSIONID 쿠키를 삭제하여 세션 추적을 종료.

 

 

7) 세션 관리 설정

.sessionManagement(session -> session
		.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
		.maximumSessions(1)
		.maxSessionsPreventsLogin(false)
		.sessionRegistry(sessionRegistry())
	)

sessionManagement(): 세션 관리 설정을 정의.
sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED): 세션 생성 정책을 설정. IF_REQUIRED는 필요한 경우에만 세션을 생성하도록 설정.
maximumSessions(1): 하나의 사용자 계정에 대해 동시에 활성화할 수 있는 최대 세션 수를 설정. 여기서는 1로 설정하여 동시 로그인 수를 제한.
maxSessionsPreventsLogin(false): 기존 세션이 있을 때 새로운 로그인 시도를 허용할지 여부를 설정. false로 설정하면 새로운 로그인 시도가 기존 세션을 종료.
sessionRegistry(sessionRegistry()): 세션 레지스트리 빈을 설정하여 세션을 관리.

 

 

8) 필터 추가

http.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class);

addFilterBefore(): 특정 필터를 다른 필터 앞에 추가.
corsFilter(): CORS 필터를 UsernamePasswordAuthenticationFilter 앞에 추가하여 CORS 정책이 먼저 적용되도록 한다.

 

 

9) CORS 필터와 설정

@Bean
public CorsFilter corsFilter() {
	return new CorsFilter(corsConfigurationSource());
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
	CorsConfiguration config = new CorsConfiguration();
	config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
	config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
	config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
	config.setAllowCredentials(true);
	
	UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
	source.registerCorsConfiguration("/**", config);
	
	return source;
}

CorsFilter: CORS 설정을 처리하는 필터를 생성.
CorsConfigurationSource: CORS 설정을 정의하는 소스.
setAllowedOrigins(): 허용할 출처(Origin)를 설정합니다. 여기서는 (리액트) http://localhost:3000을 허용.
setAllowedMethods(): 허용할 HTTP 메서드를 설정합니다. 여기서는 GET, POST, PUT, DELETE, OPTIONS 메서드를 허용.
setAllowedHeaders(): 허용할 HTTP 헤더를 설정.
setAllowCredentials(true): 자격 증명(쿠키, 인증 정보)을 허용할지 여부를 설정.
UrlBasedCorsConfigurationSource: URL 경로에 기반한 CORS 설정 소스.

 

 

10) 세션 레지스트리와 이벤트 퍼블리셔

@Bean
public SessionRegistry sessionRegistry() {
	return new SessionRegistryImpl();
}

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
	return new HttpSessionEventPublisher();
}

SessionRegistry: 세션의 상태를 추적하고 관리하는 인터페이스. 여기서는 SessionRegistryImpl 구현체를 사용.
HttpSessionEventPublisher: 세션의 생성 및 소멸과 같은 이벤트를 퍼블리싱하여 다른 컴포넌트가 이를 처리할 수 있게 한다. 이 빈은 세션과 관련된 이벤트를 처리할 때 사용.