문제

나는 REST API에 FosrestBundle을 사용하고 있으며 지금까지 훌륭한 도구였습니다. 나는 HTTP 기본 인증을 사용하고 대부분의 경우 잘 작동합니다. 그러나 불량 자격 증명이 제출 될 때 번들의 예외 동작에 문제가 있습니다. 예외를 처리 할 때 (통합 인증 처리 핸들러 또는 예외 매핑 구성을 통해) 번들은 항상 올바른 HTTP 상태 및 JSON/XML 컨텐츠에 대한 응답을 제공합니다.

{
   "code": 401,
   "message": "You are not authenticated"
}

이것은 괜찮습니다. 또한 작동합니다 인증이 없습니다 정보는 전혀 제출됩니다. 그러나 제출할 때 잘못된 자격 증명 (예 : 알 수없는 사용자 이름 또는 잘못된 암호) 빈 메시지 본문이있는 HTTP 코드 401 불량 자격 증명 (괜찮음)을 얻습니다. 대신, 나는 위의 JSON과 비슷한 것을 기대했을 것입니다.

내 측면의 버그 또는 구성 문제입니까? 또한 이런 종류의 인증 오류가 어떻게 번들에 의해 정확하게 처리되는지 알고 싶습니다. BadCredentialsException의 상태 코드 codes 번들의 예외 구성 섹션 섹션은 무시한 것 같습니다.

감사!

도움이 되었습니까?

해결책

좋아, 번들의 코드를 좀 더 파낸 후, 나는 그것을 알아 냈습니다. 문제는 Symfony의 HTTP 기본 인증 장애에 의해 잘못된 자격 증명을 처리하는 방식으로 인해 발생합니다. 그만큼 401 Bad Credentials 응답은 사용자 정의 응답입니다 BasicAuthenticationEntryPoint, 이것은 BasicAuthenticationListener'에스 handle AN 직후 기능 AuthenticationException 같은 기능으로 던져졌습니다. 따라서 청취자와 함께이 예외를 포착하는 방법은 없습니다.

public function handle(GetResponseEvent $event)
{
    $request = $event->getRequest();

    if (false === $username = $request->headers->get('PHP_AUTH_USER', false)) {
        return;
    }

    if (null !== $token = $this->securityContext->getToken()) {
        if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
            return;
        }
    }

    if (null !== $this->logger) {
        $this->logger->info(sprintf('Basic Authentication Authorization header found for user "%s"', $username));
    }

    try {
        $token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
        $this->securityContext->setToken($token);
    } catch (AuthenticationException $failed) {
        $this->securityContext->setToken(null);

        if (null !== $this->logger) {
            $this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage()));
        }

        if ($this->ignoreFailure) {
            return;
        }

        $event->setResponse($this->authenticationEntryPoint->start($request, $failed));
    }
}

진입 점 start 함수는 예외없이 사용자 정의 응답을 만듭니다.

public function start(Request $request, AuthenticationException $authException = null)
{
    $response = new Response();
    $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
    $response->setStatusCode(401, $authException ? $authException->getMessage() : null);

    return $response;
}

주먹 if-Clause handle 위의 기능은 또한 "사용자 자격 증명이 전혀 없음"의 경우에 작동하는 이유를 설명합니다.이 경우 청취자는 사용자를 인증하려고하지 않기 때문에 Symfony의 방화벽 리스너가 예외를 던지기 때문입니다 (어디에 있는지 확실하지 않습니다. 정확히), so fosrestbundle 's AccessDeniedListener 잡을 수 있습니다 AuthenticationException 그리고 그 일을하십시오.

다른 팁

당신은 확장 할 수 있습니다 AccessDeniedListener 그리고 FosrestBundle에게 매개 변수와 함께 자신의 리스너를 사용하도록 지시하십시오. %fos_rest.access_denied_listener.class%. (서비스 정의)

parameters:
    fos_rest.access_denied_listener.class: Your\Namespace\For\AccessDeniedListener

그런 다음 추가 점검을 추가하십시오 BadCredentialsException 그리고 Emmit an HttpException AuthenticationException 검사와 유사한 원하는 코드/메시지 70 행.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top