스프링 시큐리티/책 내용 정리

15. 스프링 시큐리티 애너테이션

ssjune 2023. 5. 21. 23:44

책의 15. 스프링 시큐리티 애너테이션 의 내용

SecurityConfig.java

package com.mysite.config;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import com.mysite.common.security.CustomAccessDeniedHandler;
import com.mysite.common.security.CustomLoginSuccessHandler;
import lombok.extern.slf4j.Slf4j;

@Configuration
@Slf4j
//시큐리티 애너테이션 활성화를 위한 설정
@EnableMethodSecurity(prePostEnabled=true, securedEnabled=true)
public class SecurityConfig {
	
	@Autowired
	DataSource datasource;
	
	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		log.info("security config...");
		
		http.authorizeHttpRequests((authorize) -> authorize
				.requestMatchers("/board/read")
				.permitAll());		
		
		
		//사용자가 직접 정의한 로그인 페이지의 URI를 지정한다.
		http.formLogin()
			.loginPage("/login")
			.permitAll()
			.successHandler(authenticationSuccessHandler());
		
		//접근 거부 처리자의 URI 지정
		http.authorizeHttpRequests((authorize) -> authorize
				// Allow access to the "/accessError" page
				.requestMatchers("/accessError").permitAll() 
	            .anyRequest().authenticated()
	        )
	        .exceptionHandling((except) -> except
	            .accessDeniedHandler(accessDeniedHandler())
	        );
		//로그아웃 처리를 위한 URI를 지정하고, 로그아웃 후에 세션을 무효화한다.
		http.logout().logoutUrl("/logout").invalidateHttpSession(true);

		//데이터소스를 지정하고 테이블을 이용해서 기존 로그인 정보를 기록
		http.rememberMe()
			// 랜덤한 키 값
			.key("random")
			.tokenRepository(createJDBCRepository())
			//쿠키의 유효시간을 지정한다.
			.tokenValiditySeconds(60*60*24);	
		
		return http.build();
		
	}
	

	@Bean
	public AccessDeniedHandler accessDeniedHandler() {
		return new CustomAccessDeniedHandler();
	}
	
	@Bean
	public AuthenticationSuccessHandler authenticationSuccessHandler() {
		return new CustomLoginSuccessHandler();
	}
	
	// PersistentTokenRepository 구현 클래스 객체 생성
	private PersistentTokenRepository createJDBCRepository() {
		JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl();
		repo.setDataSource(datasource);
		return repo;
	}
	
}

@PreAuthorize("hasRole('MEMBER')") 은 자동으로 ROLE_MEMBER로 변경해서 권한을 확인한다고 한다.

ROLE_MEMBER는 권한 DB에서 정의한 것으로 ROLE_TEST 이런식으로 DB에 설정하면, @PreAuthorize("hasRole('TEST')") 라고 사용할 수 있다.

 

/board/read 경로에 permitAll으로 전체 접근이 가능하게 했지만, @PreAuthorize("isAuthenticated()") 이 어노테이션이 있으면, 로그인해야만 접근이 가능하다.

반응형