권한 설정(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);
}
}
정리하자면
어노테이션을 적절히 활용하면, 애플리케이션의 메서드 수준에서 보다 세밀한 접근 제어를 구현할 수 있다.
'👩🏻💻 About 프로그래밍 > spring' 카테고리의 다른 글
JPA란? (feat. ORM) (0) | 2024.07.15 |
---|---|
사용자가 로그인을 하지않아 Exception 발생 경우 처리 방법 (1) | 2024.07.12 |
스프링 시큐리티 SecurityConfig 설정(스프링부트 2.x.x vs 3.x.x) (0) | 2024.07.10 |
스프링 시큐리티(Spring Security) vs 전통적인 방식 (0) | 2024.07.10 |
MVC1과 MVC2 비교 (0) | 2024.07.10 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기