ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot 2-메서드가 컨트롤러 또는 비동기 서비스를 통해 트리거되는지 식별
    카테고리 없음 2021. 2. 22. 22:52

    Spring Boot 2-메서드가 컨트롤러 또는 비동기 서비스를 통해 트리거되는지 식별

    1. 질문(문제점):

    스프링 부트 마이크로 서비스 애플리케이션이 있습니다. 나는 다음과 같은 요구 사항이 있습니다.

    • 컨트롤러를 통해 메서드를 호출하면 (예 : 일부 사용자 히트 API) 응답은 로그인 한 사용자의 사용자 이름이어야합니다.
    • 예약 된 작업과 같은 비 컨트롤러에서 메소드를 호출하면 Async 메소드 등의 응답이 기본 사용자 즉 시스템이어야합니다.

    따라서이 논리를 작성하려는 UserDetailService 메서드가 있습니다.

    @Service
    public class UserDetailsService
    {
        @Autowired
        WebClient.Builder webClientBuilder;
    
        @Autowired
        HttpServletRequest request;
    
        @Value("${common.serverurl}")
        private String reqUrl;
    
        public UserReturnData getCurrentUser()
        {
            if (request == null)
            {
                UserReturnData userDetails = new UserReturnData();
                userDetails.setId((long) 404);
                userDetails.setUsername("system");
                return userDetails;
            } else
            {
                UserReturnData userDetails = webClientBuilder.build().get().uri(reqUrl + "user/me")
                        .header("Authorization", request.getHeader("Authorization")).retrieve()
                        .bodyToMono(UserReturnData.class).block();
                return userDetails;
            }
        }
    }
    

    메서드가 컨트롤러에서 트리거되는지 확인하기 위해 HttpServletRequest를 자동 연결하고 null과 비교했습니다. 그러나 이것이 Async 서비스에서 트리거되면 "실제 웹 요청 외부의 요청 속성을 참조합니까"예외가 발생합니다.

    메서드가 트리거되는 위치를 식별하는 다른 방법이 있습니까? 컨트롤러가 관련된 경우, 즉 일부 API 호출이 관련된 경우 로그인 한 사용자를 반환하고 기본 사용자를 반환하는 경우 논리는 간단합니다.

    2. 해결방안:

    SecurityContextHolder 를 사용하여 현재 스레드가 로그인 한 사용자와 연결되어 있는지 확인할 수 있습니다. 다음 방법은 사용을 보여줍니다.

    public String getCurrentUser() {
        String userName="SYSTEM";
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication!=null && !(authentication instanceof AnonymousAuthenticationToken)) {
            userName = authentication.getName();
        }
        return userName;
    }
    

    @Sridhar Patnaik 제공. RG의 의견을 참조하여 아래와 같이 처리했습니다.

    1. 자동 연결 HttpServletRequest 제거
    2. 생성 된 요청 변수 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes ()) .getRequest ();
    3. 요청에 null 검사를 추가했습니다. 따라서 컨트롤러가 관련된 경우 요청은 null이 아니고 로그인 한 사용자가 반환됩니다. 그렇지 않으면 시스템 사용자가 반환됩니다.
    @Service
    public class UserDetailsService
    {
        @Autowired
        WebClient.Builder webClientBuilder;
    
        /*
         * @Autowired HttpServletRequest request;
         */
    
        @Value("${common.serverurl}")
        private String reqUrl;
    
        public UserReturnData getCurrentUser() throws Exception
        {
            try
            {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getRequest();
                if (request == null)
                {
                    UserReturnData userDetails = new UserReturnData();
                    userDetails.setId((long) 404);
                    userDetails.setUsername("system");
                    return userDetails;
                }
    
                else
                {
                    UserReturnData userDetails = webClientBuilder.build().get().uri(reqUrl + "user/me")
                            .header("Authorization", request.getHeader("Authorization")).retrieve()
                            .bodyToMono(UserReturnData.class).block();
                    return userDetails;
                }
    
            } catch (Exception e)
            {
                throw new Exception("Something Went Wrong !");
            }}
    
    65838291

    댓글

Designed by Tistory.