<aside> 1️⃣ Annotation을 직접 만들어서 사용해보자는 결심이 들었다.

</aside>

  1. config 패키지에 annotation 패키지를 생성한다.
  2. annotation패키지에 아래의 클래스들을 생성한다
/**
 * 시큐리티 authentication을 주입하는 커스텀 annotation
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface InjectAuthentication {
}
@Aspect
@Component
public class AuthenticationAspect {

    @Around("@annotation(com.jinan.profile.config.annotation.InjectAuthentication)")
    public Object injectAuthentication(ProceedingJoinPoint joinPoint) throws Throwable {
        // 인증 객체 가져오기
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        // ThreadLocal을 사용하여 현재 스레드에 인증 객체 저장
        CurrentUserContextHolder.set(authentication);

        // 메서드를 실행한다.
        Object result = joinPoint.proceed();

        // 메서드 실행 후 ThreadLocal에서 인증 객체 제거
        CurrentUserContextHolder.clear();

        return result;
    }
}
/**
 * CurrentUserContextHolder라는 ThreadLocal을 사용하여 현재 스레드에 인증 객체를 저장하고, 이를 메서드 내부에서 사용할 수 있도록 한다.
 */
public class CurrentUserContextHolder {

    private static final ThreadLocal<Authentication> context = new ThreadLocal<>();

    public static void set(Authentication authentication) {
        context.set(authentication);
    }

    public static Authentication get() {
        return context.get();
    }

    public static void clear() {
        context.remove();
    }
}

<aside> 1️⃣ 사용방법

</aside>

// 상단에 이렇게 만들어준 어노테이션을 적는다.
@InjectAuthentication
@PostMapping("/createBoard")
public String createBoard(@RequestBody BoardRequest request) {

    // 현재 인증된 사용자의 loginId 가져오기 - 어노테이션이 동작해서 세팅된 값을 가져온다.
    Authentication authentication = CurrentUserContextHolder.get();
    String loginId = authentication.getName();

    // 사용자 로그인id를 사용하여 사용자의 전체 정보 가져오기 (예: 서비스 또는 리포지토리에서)
    User user = Optional.ofNullable(userService.findByLoginId(loginId))
            .map(User::of)
            .orElseThrow(() -> new ProfileApplicationException(ErrorCode.USER_NOT_FOUND));

    // 사용자 정보를 request에 추가
    request.setUser(user);

    boardService.createBoard(request);
    return "redirect:/board/list";
}

<aside> 1️⃣ 결론

</aside>

<aside> 1️⃣ 해결방안

</aside>

사실, **SecurityContextHolder**를 직접 컨트롤러에서 사용하는 것은 좋은 설계 방식은 아닙니다. 컨트롤러는 주로 요청을 처리하고 응답을 반환하는 역할에 집중하게 설계하는 것이 좋습니다. **SecurityContextHolder**와 같은 보안 관련 로직을 컨트롤러에 직접 넣는 것은 관심사의 분리 원칙에 위배될 수 있습니다.

일반적인 설계 원칙에 따르면: