Spring Boot

Spring Security SecurityFilterChain 설정

박도치 2023. 6. 1. 18:21

Spring Security에서 URL + /login을 하게되면 Spring Security에서 제공해주는 로그인 Form을 클라이언트에 띄워준다.

 

로그인 Form 클라이언트를 제공받아 쓰는것이 아닌 직접 커스텀해서 쓰려면 기본적인 설정이 필요하다.

 

먼저 Config 에 SecurityConfig Class를 생성해준다.

기존에는 WebSecurityConfigurerAdapter를 extends 하여 overide하는식으로 등록해줬으나, 스프링 부트가 업데이트 되면서 Deprecated됨에 따라 SecurityFilterChain을 Bean에 등록하여 만들어주는 방식을 사용합니다.

 

기존 WebSecurityConfigurerAdapter 를 extends하는 방식 (비추천)

@Configuration
@EnableWebSecurity //스프링 시큐리티 필터가 스프링 필터체인에 등록됨
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) //Secured 어노테이션 활성화, PreAuthorize, PostAuthorize 어노테이션 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter{
	
	@Autowired
	private PrincipalOauth2UserService principalOauth2UserService; 

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable();
		http.authorizeRequests()
				.antMatchers("/user/**").authenticated() //인증만 되면 들어갈 수 있는 주소
				.antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")
				.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
				.anyRequest().permitAll()
				
				.and()
				
				.formLogin()
				.loginPage("/loginForm")
				.loginProcessingUrl("/login") // /login 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그인을 진행해준다.
				.defaultSuccessUrl("/")
                
     }
  }

 

 

변경된 SecurityFilterChain 을 Bean에 등록하여 사용하는 방법(추천)

 

@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터 체인에 등록됨
public class SecurityConfig {

	@Bean
	public SecurityFilterChain filter(HttpSecurity http) throws Exception {
		http.csrf().disable()
			.authorizeRequests()
            .antMatchers("/user/**").authenticated()
            .antMatchers("/manager/**").hasAuthority("MANAGER") //hasRole 은 풀네임을 써줘야 하지만, hasAuthority는 앞에 ROLE_ 이 붙기 때문에 
            .antMatchers("/admin/**").hasAuthority("ADMIN")// hasRole("ROLE_ADMIN") == hasAuthority("ADMIN") 이다.
            .anyRequest().permitAll() // 권한 설정, 해당페이지(antMatchers) 설정한 곳은 권한(hasAuthority)이 있어야 들어갈 수 있다.
            
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 스프링 시큐리티가 생성하지 않고 기존것도 사용하지 않는다(JWT Token 사용할때 설정)
            
            .and()
            
            .formLogin() //formLogin 형태
            .loginPage("/login") //loginpage를 낚아챔
            .loginProcessingUrl("/login")
            .defaultSuccessUrl("/") ; // 로그인 이후에 이동할 페이지
            
		return http.build();
	}
	
}

 

여기서 기존 Controller에 user, manager, admin을 임시로 넣어 테스트해보면 권한으로 인해 접근이 불가능 한 것을 알 수 있다. 그리고 login도 기존 Spring Security에서 주는 방식이 아닌 내가 원하는 방식으로 만들 수 있게 된다.

 

테스팅을 하기 위해 permitAll()이후는 잠시 주석처리해도 된다.

 

@GetMapping("/user") //@ResponseBody 는 페이지를 만들지 않고 해당 문자만 return해서 테스팅하기위해 사용
public @ResponseBody  String user() {
    return "user";
}

@GetMapping("/admin")
public @ResponseBody  String admin() {
    return "admin";
}

@GetMapping("/manager")
public @ResponseBody  String manager() {
    return "manager";
}

@GetMapping("/login")
public @ResponseBody String login() {
    return "login";
}

 

이후 user로 로그인하면 user는 접근이 되지만 manager, admin은 접근이 되지 않는것을 볼 수 있다. (권한설정을 했기 때문이다.)

 

formLogin설정으로 login controller가 return되는 모습이다.

403은 권한이 없어서 접근이 불가하다는 말이다.