2012-05-24 94 views
1

我被迫從我的web服務中刪除CXF。爲了除去對認證的依賴,我設置了一個HttpAuthSupplier類來處理基本認證。JAX-WS客戶端基本認證

public class ExchangeAuthSupplier implements HttpAuthSupplier{ 
     @Override 
     public boolean requiresRequestCaching() { 
      return false; 
     } 

     @Override 
     public String getAuthorization(AuthorizationPolicy authPolicy, URL url, Message message, String fullHeader) { 
      // Lookup authentication information and return appropriate header 
     } 

} 

我試圖找出我怎麼能使用常規JAX-WS API和Spring做類似的事情......

+0

你被允許使用Spring WS sundaramss? –

+0

是的,我是...我正在考慮現在最好的方法是實現一個肥皂處理程序... –

回答

7

回答我的問題...我決定去使用處理程序。因此,我創建一種SOAPHandler類似ExchangeAuthSupplier以上:

public class MyAuthenticationHandler implements SOAPHandler<SOAPMessageContext> { 
    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     final Boolean outInd = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

     if (outInd.booleanValue()) { 
      try { 
       UserNamePasswordPair userNamePasswordPair = getAuthorization(); // Method to retrieve credentials from somewhere 

       context.put(BindingProvider.USERNAME_PROPERTY, userNamePasswordPair.getUsername()); 
       context.put(BindingProvider.PASSWORD_PROPERTY, userNamePasswordPair.getPassword()); 

      } catch (final Exception e) { 
       return false; 
      } 
     } 

     return true; 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext context) { 
     logger.error("error occurred when getting auth."); 
     return false; 
    } 

    @Override 
    public void close(MessageContext context) { 
     logger.debug("closing handler for auth..."); 
    } 

    @Override 
    public Set<QName> getHeaders() { 
     return null; 
    } 
} 

創建一個HandlerResolver的解析器添加到鏈:

public class MyHandlerResolver implements HandlerResolver { 
    private List<Handler> chain; 

    public MyHandlerResolver() { 
     chain = new ArrayList<Handler>(); 
     chain.add(new MyAuthenticationHandler(); 
    } 

    @Override 
    public List<Handler> getHandlerChain(PortInfo portInfo) { 
     return chain; 
    } 
} 

然後在春天,剛剛迷上了這一切是這樣的:

<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"> 
    <property name="serviceInterface" value="Interface to implement"/> 
    <property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/> 
    <property name="namespaceUri" value="namespace"/> 
    <property name="serviceName" value="ServiceName"/> 
    <property name="endpointAddress" value="/endpoint"/> 
    <property name="handlerResolver" ref="myHandlerResolver"/> 
</bean> 

<bean id="myHandlerResolver" class="com.mystuff.ExchangeHandlerResolver"/> 
5

對於基本身份驗證和Spring的JaxWsPortProxyFactoryBean,你可以簡單地使用:

<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"> 
    <property name="serviceInterface" value="Interface to implement"/> 
    <property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/> 
    <property name="namespaceUri" value="namespace"/> 
    <property name="serviceName" value="ServiceName"/> 
    <property name="endpointAddress" value="/endpoint"/> 
    <property name="username" value="username"/> 
    <property name="password" value="password"/> 
</bean> 
0

添加到kaczors回答與Spring的JaxWsPortProxyFactoryBean, 基本身份驗證如果WSDL或XSD是不是在classpath中,需要從哪些需要基本身份驗證的訪問的URL,創建一個自定義JaxWsPortProxyFactoryBean這將使WSDL URL HTTP基本認證。

公共類CustomJaxWsPortProxyFactoryBean擴展JaxWsPortProxyFactoryBean {

@Override 
public Service createJaxWsService() { 

    Authenticator.setDefault(new Authenticator() { 
     @Override 
     protected PasswordAuthentication getPasswordAuthentication() { 
      return new PasswordAuthentication(
        getUsername(), 
        getPassword().toCharArray()); 
     } 
    }); 
    return super.createJaxWsService(); 
} 

感謝的spring forums

+0

警告:Authenticator.setDefault是靜態的,因此如果兩個請求在同一時間進行,則從一個請求將泄漏到另一個請求中。如果你打算使用它,你應該創建一個自定義的Authenticator,它使用ThreadLocal來確保每個線程使用獨立的信息,但是一般來說,我認爲避免它是更安全的。 – Trejkaz