Java 在加密前修改CXF RequestSecurityToken的XML

Java 在加密前修改CXF RequestSecurityToken的XML,java,web-services,wcf,cxf,ws-security,Java,Web Services,Wcf,Cxf,Ws Security,我正在使用ApacheCXF从Java客户机调用WCF服务。该服务使用另一地址的STS进行保护。我已经将服务客户端配置为在调用主服务之前调用安全令牌,它可以工作(它试图调用STS),但是STS希望在RequestSecurityToken元素中提供一些额外的数据。STS的政策规定,RequestSecurityToken在发送之前必须进行加密和签名,这就是导致问题的原因。加密和签名正在工作,但我似乎无法在SOAP消息被加密之前对其进行修改 我研究了这个问题:虽然它有很大帮助,但我需要修改的XML

我正在使用ApacheCXF从Java客户机调用WCF服务。该服务使用另一地址的STS进行保护。我已经将服务客户端配置为在调用主服务之前调用安全令牌,它可以工作(它试图调用STS),但是STS希望在
RequestSecurityToken
元素中提供一些额外的数据。STS的政策规定,
RequestSecurityToken
在发送之前必须进行加密和签名,这就是导致问题的原因。加密和签名正在工作,但我似乎无法在SOAP消息被加密之前对其进行修改

我研究了这个问题:虽然它有很大帮助,但我需要修改的XML部分驻留在SOAP消息的加密和签名部分中

我制作了一个
拦截器
,并在我能找到的所有不同阶段上进行了尝试,但在创建
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>
这或多或少是我的代码-我应该在哪里修改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();
CXFBusFactory bf=新的CXFBusFactory();
总线=bf.createBus();
STSClient STSClient=新的STSClient(总线);
Map stsprroperties=newhashmap();
stsprroperties.put(SecurityConstants.ENCRYPT_CRYPTO,stsMerlin);
stsprroperties.put(SecurityConstants.SIGNATURE_CRYPTO,stsMerlin);
stsprroperties.put(SecurityConstants.IS_BSP_兼容,“false”);
stsClient.setProperties(stsprroperties);
stsClient.setWsdlLocation(“http://localhost:8090/SecurityTokenService?wsdl");
stsClient.setServiceName(“{http://tempuri.org/}服务);;
stsClient.setEndpointName(“{http://tempuri.org/}服务(港口);;
stsClient.setKeySize(192);
stsClient.getInInterceptors().add(新的LogginInterceptor());
stsClient.getOutiterCeptors().add(新的LoggingOutiterCeptor());
stsClient.setTokenType(“http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1");
stsClient.setSoap12();
//在总线上设置STS客户端
bus.setProperty(SecurityConstants.STS_客户端、stsClient);
BusFactory.setDefaultBus(总线);
BusFactory.setThreadDefaultBus(总线);
MyService MyService=newmyservice();
IMyService myserviceceport=myService.getCustomBindingIMyService();
Map ctx=((BindingProvider)myServicePort.getRequestContext();
ctx.put(SecurityConstants.ENCRYPT_CRYPTO,merlin);
ctx.put(SecurityConstants.SIGNATURE_CRYPTO,merlin);
ctx.put(SecurityConstants.IS_BSP_兼容,“false”);
myServicePort.doSomething();

任何见解都值得赞赏。

因此我最终从cxf用户邮件列表中获得了一些帮助

答复如下:

我建议您在这里做的是在CXF中对STSClient进行子类化:

特别是,您希望在此处覆盖“issue”方法:

只需复制现有的方法代码,然后在 结束


果然,我对
STSClient
进行了子类化,并能够复制粘贴覆盖
issue
方法,该方法允许您访问包含
RequestSecurityToken
W3CDOMStreamWriter
,因此我可以通过执行更多
writer.writestartement(…)来进行任何修改
等。在最后的
writeedelement()之前

我想我不能给自己奖金-哦,好吧:(
  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();