使用 Camel CXF 的 SoapHeaderAuthentication 中的响应消息记录问题

Response message logging issue in SoapHeaderAuthentication with Camel CXF

我正在为我的网络服务使用 camel cxf,并希望验证来自 soap UI 的点击凭证。为此,我正在使用 cxf 拦截器,post 正在验证哪个凭据,但我无法在 Soap UI 响应中以 json/xml 格式打印错误消息。

下面是我的蓝图:-

<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();
}

}

肥皂UI的回应:-

在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)

如果我提供了错误的凭据,谁能帮助我如何在 soap UI 中打印错误消息?

实施 ContainerRequestFilter 解决了这个问题。更多建议,请post吧。

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

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