Repository: cxf Updated Branches: refs/heads/master 779cf32e4 -> 7851f41bb
[CXF-5768] - Fallback to "Issue" if "Renew" fails in the STSClient Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/7851f41b Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/7851f41b Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/7851f41b Branch: refs/heads/master Commit: 7851f41bb4ce8f658d9f6a23582d711f08571043 Parents: 779cf32 Author: Colm O hEigeartaigh <[email protected]> Authored: Tue May 27 12:17:02 2014 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Tue May 27 12:17:02 2014 +0100 ---------------------------------------------------------------------- .../cxf/ws/security/SecurityConstants.java | 7 +++ .../IssuedTokenInterceptorProvider.java | 33 ++++++++-- .../cxf/systest/sts/renew/SAMLRenewTest.java | 9 +++ .../apache/cxf/systest/sts/renew/DoubleIt.wsdl | 3 + .../apache/cxf/systest/sts/renew/cxf-client.xml | 65 ++++++++++++++------ .../cxf/systest/sts/renew/cxf-service.xml | 6 ++ .../cxf/systest/sts/renew/cxf-sts-pop.xml | 11 +++- 7 files changed, 111 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java index 993c0c0..3eb12b8 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java @@ -432,6 +432,13 @@ public final class SecurityConstants { public static final String STS_TOKEN_DO_CANCEL = "ws-security.sts.token.do.cancel"; /** + * Whether to fall back to calling "issue" after failing to renew an expired token. Some + * STSs do not support the renew binding, and so we should just issue a new token after expiry. + * The default is true. + */ + public static final String STS_ISSUE_AFTER_FAILED_RENEW = "ws-security.issue.after.failed.renew"; + + /** * Set this to "false" to not cache a SecurityToken per proxy object in the * IssuedTokenInterceptorProvider. This should be done if a token is being retrieved * from an STS in an intermediary. The default value is "true". http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java index 42746ba..c08a078 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java @@ -26,10 +26,13 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.namespace.QName; import org.w3c.dom.Element; +import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.interceptor.Fault; @@ -74,6 +77,8 @@ import org.apache.wss4j.policy.model.Trust13; */ public class IssuedTokenInterceptorProvider extends AbstractPolicyInterceptorProvider { + private static final Logger LOG = LogUtils.getL7dLogger(IssuedTokenInterceptorProvider.class); + private static final long serialVersionUID = -6936475570762840527L; private static final String ASSOCIATED_TOKEN = IssuedTokenInterceptorProvider.class.getName() + "-" + "Associated_Token"; @@ -437,10 +442,30 @@ public class IssuedTokenInterceptorProvider extends AbstractPolicyInterceptorPro client.setTemplate(itok.getRequestSecurityTokenTemplate()); return client.renewSecurityToken(tok); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new Fault(e); + } catch (RuntimeException ex) { + LOG.log(Level.WARNING, "Error renewing a token", ex); + boolean issueAfterFailedRenew = + MessageUtils.getContextualBoolean( + message, SecurityConstants.STS_ISSUE_AFTER_FAILED_RENEW, true + ); + if (issueAfterFailedRenew) { + // Perhaps the STS does not support renewing, so try to issue a new token + return issueToken(message, aim, itok); + } else { + throw ex; + } + } catch (Exception ex) { + LOG.log(Level.WARNING, "Error renewing a token", ex); + boolean issueAfterFailedRenew = + MessageUtils.getContextualBoolean( + message, SecurityConstants.STS_ISSUE_AFTER_FAILED_RENEW, true + ); + if (issueAfterFailedRenew) { + // Perhaps the STS does not support renewing, so try to issue a new token + return issueToken(message, aim, itok); + } else { + throw new Fault(ex); + } } finally { client.setTrust((Trust10)null); client.setTrust((Trust13)null); http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/renew/SAMLRenewTest.java ---------------------------------------------------------------------- diff --git a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/renew/SAMLRenewTest.java b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/renew/SAMLRenewTest.java index 013ac0b..a2fd15d 100644 --- a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/renew/SAMLRenewTest.java +++ b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/renew/SAMLRenewTest.java @@ -100,10 +100,16 @@ public class SAMLRenewTest extends AbstractBusClientServerTestBase { service.getPort(saml2PortQName, DoubleItPortType.class); updateAddressPort(saml2Port, PORT); + QName saml2NoRenewPortQName = new QName(NAMESPACE, "DoubleItTransportSaml2NoRenewPort"); + DoubleItPortType saml2NoRenewPort = + service.getPort(saml2NoRenewPortQName, DoubleItPortType.class); + updateAddressPort(saml2NoRenewPort, PORT); + // Make initial successful invocation(s) doubleIt(saml1Port, 25); doubleIt(saml1BearerPort, 30); doubleIt(saml2Port, 35); + doubleIt(saml2NoRenewPort, 35); // Now sleep to expire the token(s) Thread.sleep(8 * 1000); @@ -129,6 +135,9 @@ public class SAMLRenewTest extends AbstractBusClientServerTestBase { stsClient.setTtl(300); doubleIt(saml2Port, 35); + // Renew should fail here, but it should fall back to issue + doubleIt(saml2NoRenewPort, 35); + ((java.io.Closeable)saml1Port).close(); ((java.io.Closeable)saml1BearerPort).close(); ((java.io.Closeable)saml2Port).close(); http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/DoubleIt.wsdl ---------------------------------------------------------------------- diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/DoubleIt.wsdl b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/DoubleIt.wsdl index e260471..b586a48 100644 --- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/DoubleIt.wsdl +++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/DoubleIt.wsdl @@ -74,6 +74,9 @@ <wsdl:port name="DoubleItTransportSaml2Port" binding="tns:DoubleItTransportSaml2Binding"> <soap:address location="https://localhost:8081/doubleit/services/doubleittransportsaml2"/> </wsdl:port> + <wsdl:port name="DoubleItTransportSaml2NoRenewPort" binding="tns:DoubleItTransportSaml2Binding"> + <soap:address location="https://localhost:8081/doubleit/services/doubleittransportsaml2norenew"/> + </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingTransportSaml1Policy"> <wsp:ExactlyOne> http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-client.xml ---------------------------------------------------------------------- diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-client.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-client.xml index 5e114ab..482e80e 100644 --- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-client.xml +++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-client.xml @@ -65,32 +65,61 @@ <property name="allowRenewingAfterExpiry" value="true"/> </bean> </entry> + <entry key="ws-security.issue.after.failed.renew" value="false"/> </jaxws:properties> </jaxws:client> + + <bean id="saml2STSClient" class="org.apache.cxf.ws.security.trust.STSClient"> + <constructor-arg ref="cxf"/> + <property name="wsdlLocation" value="https://localhost:${testutil.ports.STSServerPOP}/SecurityTokenService/Transport?wsdl"/> + <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/> + <property name="endpointName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port"/> + <property name="ttl" value="8"/> + <property name="enableLifetime" value="true"/> + <property name="allowRenewingAfterExpiry" value="true"/> + <property name="properties"> + <map> + <entry key="ws-security.sts.token.username" value="myclientkey"/> + <entry key="ws-security.sts.token.properties" value="clientKeystore.properties"/> + <entry key="ws-security.sts.token.usecert" value="true"/> + </map> + </property> + </bean> + <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItTransportSaml2Port" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.username" value="alice"/> <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.sts.common.CommonCallbackHandler"/> <entry key="ws-security.signature.properties" value="clientKeystore.properties"/> <entry key="ws-security.signature.username" value="myclientkey"/> - <entry key="ws-security.sts.client"> - <bean class="org.apache.cxf.ws.security.trust.STSClient"> - <constructor-arg ref="cxf"/> - <property name="wsdlLocation" value="https://localhost:${testutil.ports.STSServerPOP}/SecurityTokenService/Transport?wsdl"/> - <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/> - <property name="endpointName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port"/> - <property name="ttl" value="8"/> - <property name="enableLifetime" value="true"/> - <property name="allowRenewingAfterExpiry" value="true"/> - <property name="properties"> - <map> - <entry key="ws-security.sts.token.username" value="myclientkey"/> - <entry key="ws-security.sts.token.properties" value="clientKeystore.properties"/> - <entry key="ws-security.sts.token.usecert" value="true"/> - </map> - </property> - </bean> - </entry> + <entry key="ws-security.sts.client" value-ref="saml2STSClient" /> + </jaxws:properties> + </jaxws:client> + + <bean id="saml2STSNoRenewClient" class="org.apache.cxf.ws.security.trust.STSClient"> + <constructor-arg ref="cxf"/> + <property name="wsdlLocation" value="https://localhost:${testutil.ports.STSServerPOP}/SecurityTokenService/TransportSoap12?wsdl"/> + <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/> + <property name="endpointName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Soap12_Port"/> + <property name="ttl" value="8"/> + <property name="enableLifetime" value="true"/> + <property name="allowRenewingAfterExpiry" value="true"/> + <property name="properties"> + <map> + <entry key="ws-security.sts.token.username" value="myclientkey"/> + <entry key="ws-security.sts.token.properties" value="clientKeystore.properties"/> + <entry key="ws-security.sts.token.usecert" value="true"/> + </map> + </property> + </bean> + + <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItTransportSaml2NoRenewPort" createdFromAPI="true"> + <jaxws:properties> + <entry key="ws-security.username" value="alice"/> + <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.sts.common.CommonCallbackHandler"/> + <entry key="ws-security.signature.properties" value="clientKeystore.properties"/> + <entry key="ws-security.signature.username" value="myclientkey"/> + <entry key="ws-security.sts.client" value-ref="saml2STSNoRenewClient" /> </jaxws:properties> </jaxws:client> <http:conduit name="https://localhost:.*"> http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-service.xml ---------------------------------------------------------------------- diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-service.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-service.xml index a285dc6..7005af8 100644 --- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-service.xml +++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-service.xml @@ -42,6 +42,12 @@ <entry key="ws-security.signature.properties" value="serviceKeystore.properties"/> </jaxws:properties> </jaxws:endpoint> + <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="doubleittransportsaml2norenew" implementor="org.apache.cxf.systest.sts.common.DoubleItPortTypeImpl" endpointName="s:DoubleItTransportSaml2NoRenewPort" serviceName="s:DoubleItService" depends-on="ClientAuthHttpsSettings" address="https://localhost:${testutil.ports.Server}/doubleit/services/doubleittransportsaml2norenew" wsdlLocation="org/apache/cxf/systest/sts/renew/DoubleIt.wsdl"> + <jaxws:properties> + <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.sts.common.CommonCallbackHandler"/> + <entry key="ws-security.signature.properties" value="serviceKeystore.properties"/> + </jaxws:properties> + </jaxws:endpoint> <httpj:engine-factory id="ClientAuthHttpsSettings" bus="cxf"> <httpj:engine port="${testutil.ports.Server}"> <httpj:tlsServerParameters> http://git-wip-us.apache.org/repos/asf/cxf/blob/7851f41b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-sts-pop.xml ---------------------------------------------------------------------- diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-sts-pop.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-sts-pop.xml index dd92654..d6781c3 100644 --- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-sts-pop.xml +++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/renew/cxf-sts-pop.xml @@ -107,7 +107,16 @@ <property name="encryptionUsername" value="myservicekey"/> </bean> <jaxws:endpoint xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" id="localSTS" implementor="#transportSTSProviderBean" address="https://localhost:${testutil.ports.STSServerPOP}/SecurityTokenService/Transport" wsdlLocation="src/test/resources/org/apache/cxf/systest/sts/deployment/ws-trust-1.4-service.wsdl" depends-on="ClientAuthHttpsSettings" serviceName="ns1:SecurityTokenService" endpointName="ns1:Transport_Port"> - </jaxws:endpoint> + </jaxws:endpoint> + + <bean id="transportSTSProviderNoRenewBean" class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider"> + <property name="issueOperation" ref="transportIssueDelegate"/> + <property name="validateOperation" ref="transportValidateDelegate"/> + </bean> + + <jaxws:endpoint xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" id="noRenewSTS" implementor="#transportSTSProviderNoRenewBean" address="https://localhost:${testutil.ports.STSServerPOP}/SecurityTokenService/TransportSoap12" wsdlLocation="src/test/resources/org/apache/cxf/systest/sts/deployment/ws-trust-1.4-service.wsdl" depends-on="ClientAuthHttpsSettings" serviceName="ns1:SecurityTokenService" endpointName="ns1:Transport_Soap12_Port"> + </jaxws:endpoint> + <httpj:engine-factory id="ClientAuthHttpsSettings" bus="cxf"> <httpj:engine port="${testutil.ports.STSServerPOP}"> <httpj:tlsServerParameters>
