CXF拦截器没有射击

时间:2013-06-13 07:47:57

标签: maven jboss jax-ws cxf

我创建了Web服务。它工作正常。现在我正在尝试对它进行身份验证。我正在为此目的使用CXF拦截器。由于某种原因,拦截器不会发射。我错过了什么?这是我的第一个网络服务。

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;

import org.apache.cxf.interceptor.InInterceptors;

@WebService
@InInterceptors(interceptors = "ws.BasicAuthAuthorizationInterceptor")
public class Service {

    @WebMethod
    public void test(@WebParam(name = "value") Integer value) throws Exception {
        System.out.println("Value = " + value);
    }    
}

-

package ws;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.Conduit;
import org.apache.cxf.ws.addressing.EndpointReferenceType;

public class BasicAuthAuthorizationInterceptor extends SoapHeaderInterceptor {

@Override
public void handleMessage(Message message) throws Fault {
    System.out.println("**** GET THIS LINE TO CONSOLE TO SEE IF INTERCEPTOR IS FIRING!!!");
    AuthorizationPolicy policy = message.get(AuthorizationPolicy.class);

    // If the policy is not set, the user did not specify credentials.
    // 401 is sent to the client to indicate that authentication is required.
    if (policy == null) {
        sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED);
        return;
    }

    String username = policy.getUserName();
    String password = policy.getPassword();

    // CHECK USERNAME AND PASSWORD
    if (!checkLogin(username, password)) {
        System.out.println("handleMessage: Invalid username or password for user: "
                + policy.getUserName());
        sendErrorResponse(message, HttpURLConnection.HTTP_FORBIDDEN);
    }
}

private boolean checkLogin(String username, String password) {
    if (username.equals("admin") && password.equals("admin")) {
        return true;
    }
    return false;
}

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

    // Set the response headers
    @SuppressWarnings("unchecked")
    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) {
        e.printStackTrace();
    }
}

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

}

我现在和他打了几天了。不知道该怎么去谷歌了。感谢帮助。

2 个答案:

答案 0 :(得分:8)

我找到了解决方案。我在战争项目中的MANIFEST.MF文件中缺少以下行:

依赖关系:org.apache.cxf

Maven不是自己包括这条线所以我必须找到解决方法。我发现了here。它说:在端点/处理程序(如Apache CXF)(@ InInterceptor,@ GZIP,...)上使用注释时,请记住在清单中添加适当的模块依赖项。否则,您的注释不会被JBoss Application Server 7选中并添加到注释索引中,从而导致它们被完全无声地忽略。

This是我发现如何更改MANIFEST.MF文件的地方。

简而言之,我将自定义清单文件添加到我的项目中并在pom.xml中引用它。希望这有助于某人。

答案 1 :(得分:2)

Felix提供的答案是准确的。我设法用他的指示解决了这个问题。刚刚完成的是maven配置,它允许您使用放在META-INF文件夹中的自己的MANIFEST.MF文件。

       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
                </archive>
            </configuration>
        </plugin>

以下是我正在使用的MANIFEST.MF文件内容的相关内容。

Manifest-Version: 1.0
Description: yourdescription
Dependencies: org.apache.ws.security,org.apache.cxf