2015-02-02 6 views
3

Я вызываю службу WCF с клиента Java с помощью Apache CXF. Служба защищена с использованием STS по другому адресу. Я настроил клиента службы для вызова маркера безопасности перед вызовом главной службы, и он работает (он пытается вызвать STS), но STS ожидает, что некоторые дополнительные данные будут предоставлены в элементе RequestSecurityToken. Политика STS указывает, что RequestSecurityToken должен быть зашифрован и подписан до отправки, и это вызывает у меня проблемы. Шифрование и подпись работают, но я не могу изменить SOAP-сообщение до того, как оно зашифруется.Измените XML CXF RequestSecurityToken, прежде чем он зашифруется

Я рассмотрел этот вопрос: How To Modify The Raw XML message of an Outbound CXF Request? и, хотя он очень помог, часть XML, которую мне нужно изменить, находится внутри части сообщения SOAP, которое зашифровывается и подписывается.

Я сделал Interceptor и попробовал его на всех разных этапах, которые я мог найти, но ни один из них, похоже, не вызван между созданным RequestSecurityToken и тем, что происходит шифрование и подпись.

Есть ли один? Или уже средство для добавления дополнительных элементов в RequestSecurityToken?

Редактировать для ясности:

Вот что мой RST выглядит сейчас:

<wst:RequestSecurityToken xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> 
    <wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType> 
    <wsp:AppliesTo xmlns:wsp="http://www.w3.org/ns/ws-policy"> 
     <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"> 
      <wsa:Address>http://localhost:9085/MyService</wsa:Address> 
     </wsa:EndpointReference> 
    </wsp:AppliesTo> 
    <wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</wst:TokenType> 
    <wst:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</wst:KeyType> 
    <wst:KeySize>192</wst:KeySize> 
    <wst:Entropy> 
     <wst:BinarySecret Type="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce">OlbfbuCUf3N2lNf9mhD03gfeMk0TfPI2nLWx8edlL5w=</wst:BinarySecret> 
    </wst:Entropy> 
    <wst:ComputedKeyAlgorithm>http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PSHA1</wst:ComputedKeyAlgorithm> 
    <wst:Renewing/> 
</wst:RequestSecurityToken> 

Вот что документация поставщика услуг говорит, что это должно выглядеть примерно (обратите внимание на Credentials элемент ближе к концу):

<t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"> 
    <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> 
    <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> 
     <EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> 
      <Address>http://localhost:9085/MyService</Address> 
     </EndpointReference> 
    </wsp:AppliesTo> 
    <t:Entropy> 
     <t:BinarySecret u:Id="uuid-e2d08122-45ab-45cd-80d1-46de2306836b-1" Type="http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">Ssex4V/175NCIOK1j4Mmbl47GiThOQMd</t:BinarySecret> 
    </t:Entropy> 
    <t:KeySize>192</t:KeySize> 
    <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</t:TokenType> 
    <t:KeyType>http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey</t:KeyType> 
    <Credentials> 
     <UserName type="string">username</UserName> 
     <Password type="string">password</Password> 
    </Credentials> 
    <t:ComputedKeyAlgorithm>http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1</t:ComputedKeyAlgorithm> 
</t:RequestSecurityToken> 

И это более или менее мой код - где бы я изменяю RST ?:

CXFBusFactory bf = new CXFBusFactory(); 
    Bus bus = bf.createBus(); 

    STSClient stsClient = new STSClient(bus); 
    Map<String, Object> stsProperties = new HashMap<>(); 

    stsProperties.put(SecurityConstants.ENCRYPT_CRYPTO, stsMerlin); 
    stsProperties.put(SecurityConstants.SIGNATURE_CRYPTO, stsMerlin); 
    stsProperties.put(SecurityConstants.IS_BSP_COMPLIANT, "false"); 
    stsClient.setProperties(stsProperties); 

    stsClient.setWsdlLocation("http://localhost:8090/SecurityTokenService?wsdl"); 
    stsClient.setServiceName("{http://tempuri.org/}Service"); 
    stsClient.setEndpointName("{http://tempuri.org/}Service_Port"); 

    stsClient.setKeySize(192); 

    stsClient.getInInterceptors().add(new LoggingInInterceptor()); 
    stsClient.getOutInterceptors().add(new LoggingOutInterceptor()); 

    stsClient.setTokenType("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"); 
    stsClient.setSoap12(); 

    // Set the STS Client on the bus 
    bus.setProperty(SecurityConstants.STS_CLIENT, stsClient); 

    BusFactory.setDefaultBus(bus); 
    BusFactory.setThreadDefaultBus(bus); 

    MyService myService = new MyService(); 
    IMyService myServicePort = myService.getCustomBindingIMyService(); 

    Map<String, Object> ctx = ((BindingProvider)myServicePort).getRequestContext(); 
    ctx.put(SecurityConstants.ENCRYPT_CRYPTO, merlin); 
    ctx.put(SecurityConstants.SIGNATURE_CRYPTO, merlin); 
    ctx.put(SecurityConstants.IS_BSP_COMPLIANT, "false"); 

    myServicePort.doSomething(); 

Любое понимание оценено.

ответ

2

Итак, я получил помощь от списка рассылки пользователей cxf.

Ответ был следующим:

То, что я хотел бы предложить вам здесь делать это подкласс STSClient в CXF:

https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java;h=afdaaeaa092460c5cbccd3f9723660ded9f12e2b;hb=HEAD

В частности, вы хотите, чтобы переопределить «вопрос "метод здесь:

https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java;h=4b4630e9d3fe0afab4496de0c7b0dd5df2fca292;hb=HEAD

Просто скопируйте существующий код метода + добавьте в свой собственный код по адресу конец.

Конечно, я подклассы в STSClient и смог скопировать-вставить-переопределить метод issue, который дает вам доступ к W3CDOMStreamWriter, который включает в RequestSecurityToken, так что я был в состоянии сделать какие-либо изменения, которые я хочу, просто делать больше writer.writeStartElement(...) и т.п. перед окончательным writer.writeEndElement().

+0

Думаю, я не могу дать себе щедрость - о, хорошо :( –