본문 바로가기

Language/Spring Security

메서드 기반 권한 부여 - @PreAuthorize, @PostAuthorize

728x90
  • Spring Security는 요청 수준의 권한 부여뿐만 아니라 메서드 수준에서의 권한 부여를 지원
  • 메서드 수준 권한 부여를 활성화 하기 위해서는 설정 클래스에 @EnableMethodSecurity 어노테이션을 추가
  • SpEL(Spring Expression Language) 표현식을 사용하여 다양한 보안 조건을 정의 가능

 

@EnableMethodSecurity

  • jsr250Enabled() - 기본값 false
    • JSR-250 관련 어노테이션들(@RolesAllowed, @PermitAll, @DenyAll) 을 활성화
  • prePostEnabled() - 기본값 true
    • @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter 를 활성화
  • securedEnabled() - 기본값 false
    • @Secured 활성화

@PreAuthorize

  • @PreAuthorize 어노테이션은 메소드가 실행되기 전에 특정한 보안 조건이 충족되는지 확인하는 데 사용되며 보통 서비스 또는 컨트롤러 레이어의 메소드에 적용되어 해당 메소드가 호출되기 전에 사용자의 인증 정보와 권한을 검사

 

  • 사용자의 권한이 ADMIN이면 실행
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
public void adminOnlyMethod() {
/* 관리자 역할을 가진 사용자만 실행할 수 있는 메소드 */
}

 

  • 사용자의 권한이 ADMIN 또는 USER면 실행
@PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_USER')")
public void adminOrUserMethod() {
/* 관리자 또는 일반 사용자 역할을 가진 사용자가 실행할 수 있는 메소드 */
}
  • 사용자가 인증되었다면 실행
@PreAuthorize("isAuthenticated()")
public void authenticatedUserOnlyMethod() {
/* 인증된 사용자만 실행할 수 있는 메소드 */
}
  • 매개변수 id가 인증 이름과 동일하면 실행
@PreAuthorize("#id == authentication.name")
public void userSpecificMethod(String id) {
/* 인증된 사용자가 자신의 ID에 해당하는 작업을 수행할 수 있는 메소드 */
}

@PostAuthorize

  • @PostAuthorize 어노테이션은 메소드가 실행된 후보안 검사를 수행하는 데 사용
  • @PreAuthorize와 달리 @PostAuthorize는 메소드 실행 후 결과에 대한 보안 조건을 검사하여 특정 조건을 만족하는 경우에만 사용자가 결과를 반환 받음

 

  • 반환 객체의 속성이 인증 객체의 이름과 같으면 반환
@PostAuthorize("returnObject.owner == authentication.name")
public BankAccount getAccount(Long id) {
	// 계정를 반환하지만 계정의 소유자만 결과를 볼 수 있음
	return new BankAccount();
}
  • 사용자의 권한이 ADMIN이여야하고 반환 객체의 secure가 true이여야 반환
@PostAuthorize("hasAuthority('ROLE_ADMIN') and returnObject.isSecure")
public BankAccount getSecureAndAdminAccount(Long id) {
	// 계정을 반환하지만 계정이 기밀이고 사용자가 관리자일 경우에만 결과를 볼 수 있음
	return new BankAccount();
}
  • 반환 객체가 null이 아니고 반환 객체의 status 값이 ‘APPROVED’이거나 권한이 ADMIN이여야 반환
@PostAuthorize("returnObject != null and (returnObject.status == 'APPROVED' or hasAuthority('ROLE_ADMIN'))")
public BankAccount updateRequestStatus() {
	return new BankAccount();
}
728x90