나는이 문제를 알아내는 것을 끝내지 만 나는 그렇게 할 다른 방향으로 갔다. 내 솔루션은 CXF 2.1과 그 JAX-WS 구현을 사용하여 CXF의 힘과 기존의 기존 스프링 인프라를 결합하는 것이 었습니다. CXF가 요구하는 수많은 항아리 때문에 처음에는 회의적 이었지만 결국에는 가장 쉽고 간단한 솔루션을 제공했습니다.
CXF website for client configuration의 예제를 적용하여 봄에 사용자 정의 CXF JAXWS 네임 스페이스를 사용하고 Username Token Authentication (암호 요약, nonces 및 timestamp) 및 타임 스탬프 확인에 Out Interceptor를 사용했습니다. 이 작업을 수행하는 유일한 다른 단계는 각각의 아웃 바운드 SOAP 요청에 대해 실행되는 자체 암호 호출 처리기를 만드는 것입니다.
SSL 구성의 경우 특정 http : conduit 이름으로 SSL을 작동시킬 수는 없지만 다시 CXF and its SSL support via conduits으로 바뀌 었습니다. 프로덕션 환경에 권장되지 않는 일반적인 목적을 사용해야했습니다.
다음은 설정 파일의 예입니다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<context:property-placeholder location="meta/my.properties" />
<context:component-scan base-package="com.foo" />
<import resource="remoting.xml" />
<jaxws:client id="myWebService" address="${my.endpointAddress}"
serviceClass="com.foo.my.ServicePortType">
<!-- Testing only, adds logging of entire message in and out -->
<jaxws:outInterceptors>
<ref bean="TimestampUsernameToken_Request" />
<ref bean="logOutbound" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="logInbound" />
</jaxws:inInterceptors>
<jaxws:inFaultInterceptors>
<ref bean="logOutbound" />
</jaxws:inFaultInterceptors>
<!-- Production settings -->
<!--
<jaxws:outInterceptors> <ref bean="TimestampUsernameToken_Request" />
</jaxws:outInterceptors>
-->
</jaxws:client >
<!--
CXF Interceptors for Inbound and Outbound messages
Used for logging and adding Username token/Timestamp Security Header to SOAP message
-->
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean id="TimestampUsernameToken_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken Timestamp" />
<entry key="user" value="${my.group}.${my.userId}" />
<entry key="passwordType" value="PasswordDigest" />
<entry key="passwordCallbackClass" value="com.foo.my.ClientPasswordHandler" />
</map>
</constructor-arg>
</bean>
<!--
http:conduit namespace is used to configure SSL using keystores, etc
*.http-conduit works but CXF says its only supposed to be for temporary use (not production),
well until the correct way works, we're going to use it.
-->
<http:conduit name="*.http-conduit">
<http:tlsClientParameters
secureSocketProtocol="SSL">
<!--
<sec:trustManagers>
<sec:keyStore type="JKS"
password="${my.truststore.password}"
file="${my.truststore.file}" />
</sec:trustManagers>
-->
<sec:keyManagers keyPassword="${my.keystore.password}">
<sec:keyStore type="JKS"
password="${my.keystore.password}"
file="${my.keystore.file}" />
</sec:keyManagers>
<!-- Cipher suites filters specify the cipher suite to allow/disallow in SSL communcation -->
<sec:cipherSuitesFilter>
<sec:include>.*_WITH_3DES_.*</sec:include>
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include
<sec:include>.*_WITH_DES_.*</sec:include
<sec:exclude>.*_WITH_NULL_.*</sec:exclude
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
</http:conduit>
</beans>
자바 클라이언트 암호 처리기 스프링 설정 파일 :
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;
/**
* <p>
* Provides a callback handler for use processing outbound/inbound SOAP messages.
* ClientPasswordHandler sets the password used in the WS-Security UsernameToken
* SOAP header.
*
* </p>
*
* Created: Apr 1, 2009
* @author Jared Knipp
*
*/
public final class ClientPasswordHandler implements CallbackHandler {
protected static Logger log = Logger.getLogger(ClientPasswordHandler.class);
private static final PropertyManager PROPS = PropertyManager.getInstance();
private static String PASSWORD = PROPS.getPassword();
private static boolean IS_PASSWORD_CLEAR = PROPS.getIsClearPassword();
/**
* Client password handler call back. This method is used to provide
* additional outbound (or could be inbound also) message processing.
*
* Here the method sets the password used in the UsernameToken SOAP security header
* element in the SOAP header of the outbound message. For our purposes the clear
* text password is SHA1 hashed first before it is hashed again along with the nonce and
* current timestamp in the security header.
*/
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
if(log.isDebugEnabled()) { log.debug("Setting password for UsernameToken"); }
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// Check to see if the password is already Hashed via SHA1, if not then hash it first
if(IS_PASSWORD_CLEAR) {
synchronized(this) {
PASSWORD = PasswordDigestUtil.doPasswordDigest(PASSWORD);
IS_PASSWORD_CLEAR = false;
PROPS.setIsClearPassword(IS_PASSWORD_CLEAR);
PROPS.setPassword(PASSWORD);
PROPS.saveProperties();
}
}
pc.setPassword(PASSWORD);
}
}
WSDL에 액세스 권한이 없다는 것을 명확히 설명합니다. 내가 가지고있는 문서에는 구멍 (타임 스탬프에 대한 언급 없음)이 있으므로 WSDL 정보의 예외가 나를 놀라게하지는 않을 것입니다. –
자, 실제 서비스를 호출하려면 실제 WSDL이 필요합니다.그게 전부입니다. –
따라서 WSDL에서 제외되지만 서버에 구현 될 가능성은 없습니까? 서버는 Axis의 일부 버전을 사용하는 Java (아마도 JBoss 또는 Websphere)입니다. –