5

Web サービスを作成しました。それは正常に動作します。今、私はそれに認証を実装しようとしています。そのためにCXFインターセプターを使用しています。何らかの理由でインターセプターが発砲しません。私は何が欠けていますか?これは私の最初の Web サービスです。

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

}

私は今数日間これと戦っています。もう何をグーグルするべきかわからない。助けていただければ幸いです。

4

2 に答える 2

8

私は解決策を見つけました。war プロジェクトの MANIFEST.MF ファイルに次の行がありませんでした。

依存関係: org.apache.cxf

Mavenにはこの行が含まれていなかったため、回避策を見つける必要がありました。私はそれについてここで見つけました。エンドポイント/ハンドラー (Apache CXF のもの (@InInterceptor、@GZIP、...) など) でアノテーションを使用する場合は、マニフェストに適切なモジュールの依存関係を追加することを忘れないでください。そうしないと、アノテーションは JBoss Application Server 7 によって取得されず、アノテーション インデックスに追加されず、完全に黙って無視されます。

これは、MANIFEST.MF ファイルを変更する方法を見つけた場所です。

つまり、カスタム マニフェスト ファイルをプロジェクトに追加し、それを pom.xml で参照しました。これが誰かに役立つことを願っています。

于 2013-06-17T14:14:31.843 に答える