2013-06-13 31 views
3

我已經創建了Web服務。它工作正常。現在我試圖對它進行身份驗證。爲此,我使用CXF攔截器。由於某些原因攔截者不會射擊。我錯過了什麼?這是我的第一個Web服務。CXF InInterceptor未開火

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

} 

我這個戰鬥了幾天了。不知道什麼谷歌更多。幫助表示讚賞。

回答

7

我找到了解決方案。我錯過了在MANIFEST.MF文件下面一行在戰爭中的項目:

依賴關係:org.apache.cxf

Maven的不includint此行,他自己,所以我必須找到解決辦法。我發現那個here。它說:當在端點/處理程序(如Apache CXF的處理程序(@InInterceptor,@GZIP,...))上使用註釋時,請記住在清單中添加適當的模塊依賴項。否則,您的註釋將不會被拾取並由JBoss應用服務器7添加到註釋索引中,從而導致它們被完全和靜默地忽略。

This是我發現如何更改MANIFEST.MF文件。

簡而言之,我將自定義清單文件添加到我的項目並在pom.xml中引用它。希望這可以幫助某人。

+1

+1清楚地解釋了什麼是問題,並將maven當作「男人」對待:「maven自己並不包含這一行」:) – Sikorski

2

Felix提供的答案是準確的。我設法根據他的指示解決問題。在這裏完成的是maven配置,可以讓你使用自己的MANIFEST.MF文件放置在META-INF文件夾中。

 <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