У нас есть требование установить заголовок Basic Auth Authorization для всех исходящих вызовов SOAP.Наше J2EE-приложение использует Spring, выступая в качестве SOAP-клиента.
<bean id="myServices"
class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface"
value="training.service.mybusinessservices.myBusinessServicesPort" />
<property name="wsdlDocumentUrl" value="${my.service.wsdlDocumentUrl}" />
<property name="endpointAddress" value="${my.service.endpoint}" />
<property name="namespaceUri"
value="http://training.org/myBusinessServices" />
<property name="serviceName" value="myBusinessServices" />
<property name="portName" value="myBusinessServices" />
<property name="lookupServiceOnStartup" value="false" />
<property name="handlerResolver" ref="serviceSecurityHandler" />
</bean>
Наше требование заключается в получении имени пользователя и пароля из центрального хранилища на основе вызываемого нами serviceName.Следовательно, подход состоял в том, чтобы использовать handlerResolver для установки заголовка http через перехватчик (вместо использования свойств JaxWsProxy .... имя пользователя и пароль)
Наша реализация перехватчика handlerResolver
@Override
public boolean handleMessage(SOAPMessageContext context) {
logger.debug("handleMessage()-start");
boolean isOutBound = true;
try {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(context.getMessage() !=null && outboundProperty.booleanValue()) {
MessageLogger.logMessage(AuthConstants.HANDLE_MESSAGE, "Context not null " + context.getMessage(),AuthConstants.DEBUG, null);
String sourceAppID = getValueByTagName(context,AuthConstants.SOURCE_APPID);
String channelID = getValueByTagName(context,AuthConstants.CHANNEL_ID);
logger.debug("Retrieving the basic auth token details for sourceAppID:{}, channelID:{}",sourceAppID,channelID );
/*
* Retrieve the Basic Auth Token for the key
* sourceAppID~channelID
* e.g.
* MOBILEAPP~ONLINE
* or
* MYWEBAPP~PORTAL
*/
String encodedBasicAuthCredentials = getAuthorizationDetails (sourceAppID, channelID);
String[] userDetailsPair = getUserDetailsPairFromBasicAuthCredentials(encodedBasicAuthCredentials);
logger.debug("Obtained the userDetailsPair:{}",userDetailsPair);
if(userDetailsPair !=null && userDetailsPair.length ==2) {
logger.debug("Settings the context header:{}",userDetailsPair);
logger.debug("Settings the context with username:{} and password:{}",userDetailsPair[0],userDetailsPair[1]);
context.put("javax.xml.ws.security.auth.username", userDetailsPair[0]);
context.put("javax.xml.ws.security.auth.password", userDetailsPair[1]);
//Came across a forum where it was recommended to call saveChanges() for container starting from Tomcat v8.0
context.getMessage().saveChanges();
}
else {
logger.error("The authorization header is not set because of unavailability for sourceAppID:{}, channelID:{}",sourceAppID,channelID );
}
} else {
isOutBound = false;
}
}catch (Exception e) {
logger.error("Exception in handleMessage:{}", e.getMessage());
if(logger.isDebugEnabled()){
logger.error("Exception in handleMessage:" , e);
}
}
logger.debug("handleMessage()-end");
return isOutBound;
}
Тот же код работаетнормально через Junit
Но когда я тестирую через JBOSS EAP 7.0, заметил, что заголовок Authorization не установлен.Также замечено, что внутри JBOSS CXF имеет приоритет как клиентский атрибут и не устанавливает заголовок авторизации
Любые указатели будут действительно полезны