Java 在加密前修改CXF RequestSecurityToken的XML
我正在使用ApacheCXF从Java客户机调用WCF服务。该服务使用另一地址的STS进行保护。我已经将服务客户端配置为在调用主服务之前调用安全令牌,它可以工作(它试图调用STS),但是STS希望在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
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();