권한 설정(feat. @PreAuthorize, @PostAuthorize)
by 볼빵빵오춘기더보기
SpringSecurity를 사용할 때 SecurityConfig 클래스를 만들어 filterChain() 메소드안에서 특정 url이 요청이 들어왔을 때 해당 권한이 있는 사용자만 접근 가능하도록 설정을 했었다.
하지만 그 외에도 특정 url이 붙지않아도 설정 해주고 싶을 때가 있을 수 있다.
그럴 때 Controller에서 특정 url에만 해당 권한이 있는 사용자만 접근하도록 설정해보자!
@Configuration // @EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록 @EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) // controller에 권한설정 public class SecurityConfig{ @Autowired private PrincipalOauth2UserService principalOauth2UserService; private final PrincipalDetailsService userDetailsService; public SecurityConfig(PrincipalDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public BCryptPasswordEncoder encodePwd() { return new BCryptPasswordEncoder(); } @Bean public LoginSuccessHandler loginSuccessHandler(){ return new LoginSuccessHandler(); } @Bean public LoginFailureHandler loginFailureHandler(){ return new LoginFailureHandler(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ http.formLogin((formLogin) -> formLogin.loginPage("/loginForm").loginProcessingUrl("/login").successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler())) .authorizeHttpRequests(authorize -> authorize .requestMatchers("/login").permitAll() // 추가부분 .requestMatchers("/user/**").hasAnyRole("USER","SHELTER","ADMIN") // /user/** url => user, center, admin 권한이 있는 사용자만 접근 가능 .requestMatchers("/center/**").hasAnyRole("CENTER","ADMIN") // /center/** url => center, admin 권한이 있는 사용자만 접근 가능 .requestMatchers("/admin/**").hasAnyRole("ADMIN") // /center/** url => admin 권한이 있는 사용자만 접근 가능 .anyRequest().permitAll() // 권한을 주지않은 url 이 아니면 접근 허용 ).oauth2Login((oauth2) -> oauth2 .loginPage("/loginForm").userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint .userService(principalOauth2UserService)).successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler())) ; http.csrf(CsrfConfigurer::disable).cors(Customizer.withDefaults()); return http.build(); } }
@PreAuthorize & @PostAuthorize
- Spring Security에서 메서드 수준에서 권한을 제어하기 위해 사용하는 어노테이션이다.
- 어노테이션을 사용하면 특정 메서드가 호출되기 전(@PreAuthorize)이나 호출된 후(@PostAuthorize)에 접근을 제어한다.
@PreAuthorize
메서드 실행 전에 접근 권한을 제어하고 싶을 때 사용한다.
주로 메서드 인자나 현재 인증된 사용자의 권한을 기반으로 접근을 제한한다.
ex) 특정 역할을 가진 사용자만 특정 메서드를 실행할 수 있도록 하거나, 특정 사용자만 자신의 데이터에 접근할 수 있도록 할 때 사용한다.
@PreAuthorize 사용방법
Security 설정 클래스에 메서드 보안 활성화
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) // Security 설정 클래스에 메서드 보안 활성화 public class SecurityConfig { // 기타 보안 설정 }
메서드에 @PreAuthorize 어노테이션 추가
@Service public class PreAuthorizeService { @PreAuthorize("hasRole('ROLE_ADMIN')") public void adminMethod() { // 관리자만 접근 가능한 로직 } @PreAuthorize("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')") public void userOrAdminMethod() { // 사용자 또는 관리자 접근 가능한 로직 } @PreAuthorize("#username == authentication.name") public void userSpecificMethod(String username) { // 메서드 인자와 인증된 사용자 이름이 일치해야 접근 가능한 로직 } }
@PostAuthorize
- 메서드 실행 후 반환된 결과를 기반으로 접근 권한을 제어하고 싶을 때 사용한다.
- 주로 메서드 실행 결과에 따라 접근을 제한하고자 할 때 사용한다.
ex) 메서드가 반환한 객체의 특정 필드 값이 현재 인증된 사용자와 일치하는지 확인하는 경우에 사용한다.
@PostAuthorize 사용방법
Security 설정 클래스에 메서드 보안 활성화
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) // Security 설정 클래스에 메서드 보안 활성화 public class SecurityConfig { // 기타 보안 설정 }
메서드에 @PostAuthorize 어노테이션 추가
@Service public class PostAuthorizeService { @PostAuthorize("returnObject.owner == authentication.name") public SampleObject findSampleObjectById(Long id) { // 메서드 실행 후 반환된 객체의 소유자와 인증된 사용자가 일치해야 접근 가능한 로직 return sampleObjectRepository.findById(id); } }
정리하자면
어노테이션을 적절히 활용하면, 애플리케이션의 메서드 수준에서 보다 세밀한 접근 제어를 구현할 수 있다.

블로그의 정보
Hello 춘기's world
볼빵빵오춘기