Проблема с ведением журнала ответных сообщений в SoapHeaderAuthentication с Camel CXF

Я использую camel cxf для своих веб-сервисов и хочу проверить учетные данные обращений из пользовательского интерфейса мыла. Для чего я использую перехватчики cxf, сообщаю, какие учетные данные проверяются, но я не могу распечатать сообщение об ошибке в формате json / xml в ответе пользовательского интерфейса Soap.

Ниже мой план: -

<cxf:rsServer id="testingService"
    address="http://127.0.0.1:8183/test/myWebserviceEndPoint"
    serviceClass="com.test.SerFac">
    <cxf:providers>
        <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
    </cxf:providers>
    <cxf:inInterceptors>
          <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
          <bean class="com.test.BasicAuthAuthorizationInterceptor" />
   </cxf:inInterceptors>
   <cxf:outInterceptors>
          <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
   </cxf:outInterceptors>
</cxf:rsServer>

Ниже BasicAuthAuthorizationInterceptor.java

public class BasicAuthAuthorizationInterceptor extends SoapHeaderInterceptor {

protected Logger log = Logger.getLogger(getClass());

/** Map of allowed users to this system with their corresponding passwords. */
private Map<String,String> users;

@Required
public void setUsers(Map<String, String> users) {
    this.users = users;
}

@Override public void handleMessage(Message message) throws Fault {
    // This is set by CXF
    AuthorizationPolicy policy = message.get(AuthorizationPolicy.class);

    // If the policy is not set, the user did not specify credentials
    // A 401 is sent to the client to indicate that authentication is required
    if (policy == null) {
        if (log.isDebugEnabled()) {
            log.debug("User attempted to log in with no credentials");
        }
        sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED);
        return;
    }

    if (log.isDebugEnabled()) {
        log.debug("Logging in use: " + policy.getUserName());
    }

    // Verify the password
    String realPassword = users.get(policy.getUserName());
    if (realPassword == null || !realPassword.equals(policy.getPassword())) {
        log.error("Invalid username or password for user: " + policy.getUserName());

        sendErrorResponse(message, HttpURLConnection.HTTP_FORBIDDEN);
    }
}

private void sendErrorResponse(Message message, int responseCode) {
    Message outMessage = getOutMessage(message);
    outMessage.put(Message.RESPONSE_CODE, responseCode);

    // Set the response headers
    Map<String, List<String>> responseHeaders =
        (Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS);
    if (responseHeaders != null) {
        responseHeaders.put("WWW-Authenticate", Arrays.asList(new String[]{"Basic realm=realm"}));
        responseHeaders.put("Content-Length", Arrays.asList(new String[]{"0"}));
    }
    message.getInterceptorChain().abort();
    try {
        getConduit(message).prepare(outMessage);
        close(outMessage);
    } catch (IOException e) {
        log.warn(e.getMessage(), e);
    }
}

private Message getOutMessage(Message inMessage) {
    Exchange exchange = inMessage.getExchange();
    Message outMessage = exchange.getOutMessage();
    if (outMessage == null) {
        Endpoint endpoint = exchange.get(Endpoint.class);
        outMessage = endpoint.getBinding().createMessage();
        exchange.setOutMessage(outMessage);
    }
    outMessage.putAll(inMessage);
    return outMessage;
}

private Conduit getConduit(Message inMessage) throws IOException {
    Exchange exchange = inMessage.getExchange();
    EndpointReferenceType target = exchange.get(EndpointReferenceType.class);
    Conduit conduit =
        exchange.getDestination().getBackChannel(inMessage, null, target);
    exchange.setConduit(conduit);
    return conduit;
}

private void close(Message outMessage) throws IOException {
    OutputStream os = outMessage.getContent(OutputStream.class);
    os.flush();
    os.close();
}

}

Ответ от мыльного интерфейса: -

В формате xml: -

<xml/>

В сыром виде: -

HTTP/1.1 403 Forbidden
Accept-Encoding: gzip,deflate
Authorization: Basic fLaWs3dvcmQ6cGFzc3dvcmQx
Content-Length: 0
Content-Type: application/json
Host: localhost:8183
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
WWW-Authenticate: Basic realm=realm
Server: Jetty(8.1.17.v20150415)

Может ли кто-нибудь помочь, как распечатать сообщения об ошибках в пользовательском интерфейсе мыла, если я дам неправильные учетные данные?


person SomMS    schedule 16.12.2016    source источник
comment
Может я чего-то упускаю, но где вы выкидываете Fault в случае ошибки аутентификации? Кроме того, почему вы расширяете SoapHeaderInterceptor, если вы не используете его реализацию где-либо в своем подклассе? Или ты?   -  person Ralf    schedule 20.12.2016
comment
Спасибо, Ральф, попробовал с AbstractPhaseInterceptor ‹Message› с ошибкой вместо SoapHeaderAuthentication и получил ответ в формате xml, как указано. Но я не могу преобразовать это в формат JSON. Можно ли распечатать сообщение об ошибке Fault в формате Json?   -  person SomMS    schedule 21.12.2016
comment
Fault fault = new Fault (Неверное имя пользователя или пароль для пользователя: + policy.getUserName (), java.util.logging.Logger.getGlobal ()); fault.setStatusCode (403); бросить вину;   -  person SomMS    schedule 21.12.2016
comment
SOAP подразумевает XML. Какую часть сообщения об ошибке вы хотите закодировать в формате JSON? (И почему?) Можете ли вы дополнить свой вопрос тем ответом, который вы хотели бы получить?   -  person Ralf    schedule 21.12.2016
comment
@Ralf, я использую службу Restful. Это то, что я ищу. Ответ на вкладке XML: - ‹Response xmlns = http: //..../myservice› ‹errorMessage› Неверное имя пользователя или пароль для пользователя: Test ‹/ errorMessage ›‹/Response› Ответ на вкладке JSON: - {errorMessage: Неверное имя пользователя или пароль для пользователя: Test}   -  person SomMS    schedule 21.12.2016
comment
Сервер отправит вам один ответ. В кодировке XML или JSON. Я не знаю, как вы настраиваете CXF для ответа с сообщениями в кодировке JSON.   -  person Ralf    schedule 21.12.2016
comment
Возможно, он автоматически делает правильные вещи на основе заголовка Accept, который вы отправляете в своем запросе.   -  person Ralf    schedule 21.12.2016


Ответы (1)


Реализация ContainerRequestFilter решила эту проблему. Для получения дополнительных предложений, пожалуйста, опубликуйте их.

https://community.oracle.com/docs/DOC-1003506

http://javatech-blog.blogspot.co.uk/2015/04/jax-rs-filters-example.html

person SomMS    schedule 21.07.2017