Role 체크 어노테이션 만들기 2

슈퍼콜라·2025년 7월 30일
0

클래스에 @CheckRole을 한 경우 특정 메서드는 예외로 할 수 있게 무시 어노테이션을 따로 만들어줌


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreRoleCheck {}

Aspect 만들기


@Aspect
@Component
public class RoleCheckAspect {

	// 클래스와 메서드 단위로 @CheckRole이 붙어있으면 적용
    @Around("@within(exe.annotation.CheckRole) || @annotation(exe.annotation.CheckRole)")
    public Object checkRole(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

		// 무시 어노테이션이 있으면 넘어감
        if (method.isAnnotationPresent(IgnoreRoleCheck.class)) {
            return joinPoint.proceed();
        }
		
        // 해당 메서드 또는 클래스에 @CheckRole이 없다면, 권한 체크를 하지 않고 바로 메서드를 실행
        CheckRole checkRole = findCheckRoleAnnotation(method, joinPoint.getTarget().getClass());

        if (checkRole == null) {
            return joinPoint.proceed();
        }

        return validateRoleAndProceed(joinPoint, checkRole.value());
    }

	// 메서드 → 클래스 순서로 @CheckRole 어노테이션을 찾음
    private CheckRole findCheckRoleAnnotation(Method method, Class<?> targetClass) {
        CheckRole methodAnnotation = method.getAnnotation(CheckRole.class);
        if (methodAnnotation != null) {
            return methodAnnotation;
        }
        return targetClass.getAnnotation(CheckRole.class);
    }

	// 여기서 실제 사용자 인증 정보에서 권한이 있는지 검사
    private Object validateRoleAndProceed(ProceedingJoinPoint joinPoint, String requiredRole) throws Throwable {
    	
        // 1) 인증 객체 가져오기 => 필터 과정에서 넣어준 권한을 가져옴
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || !authentication.isAuthenticated()) {
            throw new Exception("오류");
        }

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

        String normalizedRequiredRole = requiredRole.startsWith("ROLE_") ? requiredRole : "ROLE_" + requiredRole;

        boolean hasRole = authorities.stream()
                .anyMatch(auth -> auth.getAuthority().equals(normalizedRequiredRole));

        if (!hasRole) {
            throw new Exception("오류");
        }

        return joinPoint.proceed();
    }
}

profile
공부하는거 정리

0개의 댓글