prosource

Zuul을 인증 게이트웨이로 사용

probook 2023. 3. 29. 21:37
반응형

Zuul을 인증 게이트웨이로 사용

배경

는 이 기사에 제시된 디자인을 구현하고 싶습니다.

아래 다이어그램으로 요약할 수 있습니다.

  1. 클라이언트는 먼저 IDP(OpenID Connect/OAuth2)를 사용하여 인증합니다.
  2. IDP가 액세스토큰을 반환합니다(사용자 정보가 없는 비투명 토큰).
  3. 클라이언트는 Authorization 헤더 내의 액세스토큰을 사용하여 API 게이트웨이를 통해 콜을 발신합니다.
  4. API 게이트웨이는 액세스 토큰을 사용하여 IDP에 요구를 합니다.
  5. IDP는 액세스 토큰이 유효한 것을 확인하고 사용자 정보를 JSON 형식으로 반환합니다.
  6. API 게이트웨이는 사용자 정보를 JWT에 저장하고 개인 키로 서명합니다.그런 다음 JWT는 공개 키를 사용하여 JWT를 확인하는 다운스트림 서비스로 전달됩니다.
  7. 요청을 이행하기 위해 다른 서비스를 호출해야 하는 경우 해당 서비스는 요청에 대한 인증 및 승인 역할을 하는 JWT를 전달합니다.

지금까지 가지고 있는 것

대부분의 경우 다음을 사용합니다.

  • 글로벌 프레임워크로서의 봄 클라우드
  • 개별 서비스를 시작하는 스프링 부트
  • API 게이트웨이로서의 Netflix Zuul

또한 액세스 토큰을 확인하고 IDP에 연락하여 JWT를 작성하는 Zuul PRE 필터도 작성했습니다.다음으로 다운스트림서비스로 전송되는 요청의 헤더에 JWT가 추가됩니다.

문제

이제 제 질문은 Zuul과 그 필터에 대한 것입니다.어떤 이유로 API 게이트웨이에서 인증이 실패했을 경우 필터 체인을 계속하여 콜을 전송하지 않고 어떻게 루팅을 중지하고 401로 직접 응답할 수 있습니까?

현재 인증에 실패해도 필터는 헤더에 JWT를 추가하지 않고 401은 다운스트림서비스에서 가져옵니다.게이트웨이가 불필요한 전화를 막아주길 바랐어요

어떻게 하면 이 모든 것을com.netflix.zuul.context.RequestContext이렇게 하려고 했는데 서류가 형편없어서 방법을 찾을 수가 없었어요.

설정해 볼 수 있습니다.setSendZuulResponse(false)현재 컨텍스트에서.이것은 요구를 라우팅하지 않습니다.전화하실 수도 있습니다.removeRouteHost()같은 결과를 얻을 수 있습니다.사용할 수 있습니다.setResponseStatusCode401 상태 코드를 설정합니다.

실행 방법에 다음 항목을 추가하면 이 문제가 해결됩니다.

ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);

대답하기엔 너무 늦은 거 알아.주울 프리필터로 접근할 수 있습니다.다음은 사용자가 따라야 하는 단계입니다.

 //1. create filter with type pre
 //2. Set the order of filter to greater than 5 because we need to run our filter after preDecoration filter of zuul.
 @Component
 public class CustomPreZuulFilter extends ZuulFilter {

  private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Override
public Object run() {
    final RequestContext requestContext = RequestContext.getCurrentContext();
    logger.info("in zuul filter " + requestContext.getRequest().getRequestURI());
    byte[] encoded;
    try {
        encoded = Base64.encode("fooClientIdPassword:secret".getBytes("UTF-8"));
        requestContext.addZuulRequestHeader("Authorization", "Basic " + new String(encoded));

        final HttpServletRequest req = requestContext.getRequest();
        if (requestContext.getRequest().getHeader("Authorization") == null
                && !req.getContextPath().contains("login")) {
            requestContext.unset();
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());

        } else {
              //next logic
            }
        }

    } catch (final UnsupportedEncodingException e) {
        logger.error("Error occured in pre filter", e);
    }

    return null;
}



@Override
public boolean shouldFilter() {
    return true;
}

@Override
public int filterOrder() {
    return 6;
}

@Override
public String filterType() {
    return "pre";
}

}

requestContext.unset()는 현재 스레드의 활성 요청에 대한 RequestContext를 리셋하며 응답 상태 코드를 제공할 수 있습니다.

언급URL : https://stackoverflow.com/questions/37180375/using-zuul-as-an-authentication-gateway

반응형