2011-07-18 102 views
1

我在我的應用程序中使用spring security進行身份驗證,現在我使用cxf公開了一個web服務,並且我想使用spring安全性來驗證當前web服務調用。但我需要訪問證書中的Web服務調用(我使用的WS-Security)cxf服務的自定義攔截器允許彈簧安全身份驗證

這是我的CXF bean聲明的摘錄:

<jaxws:endpoint id="service2" 
        implementor="xxx.service2.CXFLibraryImpl" 
        wsdlLocation="classpath:service2.wsdl" 
        address="/service2"> 
    <jaxws:inInterceptors> 

      <bean class="com.kprtech.service.ws.service2.MyWSS4JInInterceptor"> 
      </bean> 
</jaxws:endpoint> 

這是WSDL暴露的WS-Security :

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="CXFLibraryImplService" targetNamespace="http://service2.ws.service.kprtech.com/" xmlns:ns1="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service2.ws.service.kprtech.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <wsdl:types> 
<xs:schema elementFormDefault="unqualified" targetNamespace="http://service2.ws.service.kprtech.com/" version="1.0" xmlns:ns1="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service2.ws.service.kprtech.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="sayHello" type="tns:sayHello" /> 
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse" /> 
<xs:complexType name="sayHello"> 
<xs:sequence> 
<xs:element minOccurs="0" name="arg0" type="xs:string" /> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="sayHelloResponse"> 
<xs:sequence> 
<xs:element minOccurs="0" name="return" type="xs:string" /> 
</xs:sequence> 
</xs:complexType> 
</xs:schema> 
    </wsdl:types> 
    <wsdl:message name="sayHello"> 
    <wsdl:part element="tns:sayHello" name="parameters"> 
    </wsdl:part> 
    </wsdl:message> 
    <wsdl:message name="sayHelloResponse"> 
    <wsdl:part element="tns:sayHelloResponse" name="parameters"> 
    </wsdl:part> 
    </wsdl:message> 
    <wsdl:portType name="Library"> 
    <wsdl:operation name="sayHello"> 
     <wsdl:input message="tns:sayHello" name="sayHello"> 
    </wsdl:input> 
     <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"> 
    </wsdl:output> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="CXFLibraryImplServiceSoapBinding" type="tns:Library"> 
    <wsp:PolicyReference URI="#SignEncr" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" /> 
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="sayHello"> 
     <soap:operation soapAction="" style="document" /> 
     <wsdl:input name="sayHello"> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output name="sayHelloResponse"> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="CXFLibraryImplService"> 
    <wsdl:port binding="tns:CXFLibraryImplServiceSoapBinding" name="CXFLibraryImplPort"> 
     <soap:address location="http://localhost:8888/domicilios/services/service2" /> 
    </wsdl:port> 
    </wsdl:service> 
    <wsp:Policy wsu:Id="SignEncr" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 

    <wsp:ExactlyOne> 
     <wsp:All> 
     <sp:AsymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> 
      <wsp:Policy> 
      <sp:InitiatorToken> 
       <wsp:Policy> 
       <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> 
        <wsp:Policy> 
        <sp:RequireThumbprintReference /> 
         <sp:WssX509V1Token10 /> 
        </wsp:Policy> 
       </sp:X509Token> 
       </wsp:Policy> 
      </sp:InitiatorToken> 
      <sp:RecipientToken> 
       <wsp:Policy> 
       <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> 
        <wsp:Policy> 
        <sp:RequireThumbprintReference /> 
         <sp:WssX509V3Token10 /> 
        </wsp:Policy> 
       </sp:X509Token> 
       </wsp:Policy> 
      </sp:RecipientToken> 
      <sp:AlgorithmSuite> 
       <wsp:Policy> 
       <sp:TripleDesRsa15 /> 
       </wsp:Policy> 
      </sp:AlgorithmSuite> 
      <sp:Layout> 
       <wsp:Policy> 
       <sp:Strict /> 
       </wsp:Policy> 
      </sp:Layout> 
      <sp:IncludeTimestamp /> 
      <sp:OnlySignEntireHeadersAndBody /> 
      </wsp:Policy> 
     </sp:AsymmetricBinding> 
      <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> 
       <wsp:Policy> 
        <sp:MustSupportRefKeyIdentifier /> 
        <sp:MustSupportRefIssuerSerial /> 
       </wsp:Policy> 
      </sp:Wss10> 
     <sp:SignedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> 
      <sp:Body /> 
     </sp:SignedParts> 

     </wsp:All> 
    </wsp:ExactlyOne> 
    </wsp:Policy> 
</wsdl:definitions> 

的問題是,即使我的自定義攔截器CXF使用org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor

,並試圖驗證證書S和安全令牌對一個密碼,我想做的事情在我的自定義攔截器com.kprtech.service.ws.service2.MyWSS4JInInterceptor

回答

0

我這個前一段時間解決了我自己的這個操作:

您需要一個CXF的配置如下所示:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:jaxws="http://cxf.apache.org/jaxws" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> 


    <import resource="classpath:META-INF/cxf/cxf.xml"/> 
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> 
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> 
    <import resource="classpath:META-INF/cxf/cxf-extension-policy.xml"/> 
    <import resource="classpath:META-INF/cxf/cxf-extension-ws-security.xml"/> 

    <bean id="implementorBean" class="ws.Implementor"/> 

    <jaxws:endpoint id="implementor" 
        implementor="#implementorBean" 
        wsdlLocation="/ws/server/service.wsdl" 
        address="/service"> 

     <jaxws:inInterceptors> 

      <bean class="ws.SpringSecurityInterceptor"> 

      </bean> 
     </jaxws:inInterceptors> 

     <jaxws:properties> 
      <entry key="ws-security.signature.properties" value="/ws/security/server-crypto.properties"/> 
      <entry key="ws-security.signature.username" value="serverkey"/> 
      <entry key="ws-security.callback-handler" value="ws.ServerCallback"/> 
     </jaxws:properties> 

    </jaxws:endpoint> 

</beans> 

而實現這樣一個攔截器:

public class SpringSecurityInterceptor extends AbstractWSS4JInterceptor { 

    private ThreadLocal<Subject> currentSubject = new ThreadLocal<Subject>(); 


    public SpringSecurityInterceptor() { 
     super(); 
     setPhase(Phase.PRE_PROTOCOL); 
     getAfter().add(WSS4JInInterceptor.class.getName()); 
     getAfter().add(PolicyBasedWSS4JInInterceptor.class.getName()); 
    } 


    public void handleMessage(SoapMessage message) throws Fault { 

     try { 

      Subject subject = (Subject) currentSubject.get(); 

      if (subject == null) { 
       subject = new Subject(); 
       currentSubject.set(subject); 
      } 
      List<Object> results = (List<Object>)message.get(WSHandlerConstants.RECV_RESULTS); 
      if (results == null) { 
       return; 
      } 
      for (Iterator iter = results.iterator(); iter.hasNext();) { 
       WSHandlerResult hr = (WSHandlerResult) iter.next(); 
       if (hr == null || hr.getResults() == null) { 
        return; 
       } 

        for (Iterator it = hr.getResults().iterator(); it.hasNext();) { 
         WSSecurityEngineResult er = (WSSecurityEngineResult) it.next(); 

         if (er != null && er.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE) instanceof X509Certificate) { 
          X509Certificate cert = (X509Certificate)er.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE); 

           // TODO do something with the certificate 

         } 
        } 

      } 

      message.put(Subject.class, subject); 

     } catch (java.lang.reflect.UndeclaredThrowableException e) { 
      Throwable undeclared = e.getUndeclaredThrowable(); 
      if (undeclared != null 
        && undeclared instanceof java.lang.reflect.InvocationTargetException) { 
       throw new Fault(
         ((java.lang.reflect.InvocationTargetException) undeclared) 
           .getTargetException()); 
      } 

     } finally { 
      currentSubject.set(null); 
     } 
    } 


} 
相關問題