[
https://issues.apache.org/jira/browse/AXIS2-5904?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Robert Lazarski resolved AXIS2-5904.
------------------------------------
Fix Version/s: 2.0.1
Resolution: Fixed
Fixed in commits 118dcca, 18fd259, a4f18f6, efa70b7 on master (will ship
in 2.0.1).
Root cause: AxisBindingMessage.getEffectivePolicy() and
AxisMessage.getEffectivePolicy() used Date.after() to detect policy
changes in the description hierarchy. java.util.Date has millisecond
granularity — two policy updates within the same millisecond produced
identical timestamps, causing isPolicyUpdated() to return false and the
cached (potentially null) effective policy to be returned. This
manifested as intermittent "Rampart policy configuration missing" errors
on consecutive secured SOAP calls, as Andreas Veithen diagnosed in Jan
2018.
Fix: Replaced Date-based timestamp comparison with a monotonic AtomicLong
counter in PolicySubject. Every policy mutation (attach, detach, update,
clear) increments a global counter. isPolicyUpdated() now compares
version numbers instead of timestamps — guaranteed unique, strictly
increasing, zero granularity issues. The fix applies to both
AxisBindingMessage and AxisMessage, which are the two classes in the
hierarchy that cache effective policies. The deprecated Date-based
getLastUpdatedTime()/setLastUpdatedTime() API is preserved in
PolicySubject for backward compatibility.
Tests: Added PolicyCacheRaceTest (5 tests) covering version monotonicity
on attach/detach/clear, effective policy detection after update, and a
rapid-fire 100-iteration scenario simulating the same-millisecond race.
Full kernel test suite (402 tests) passes.
Note for Rampart 2.0.0: This fix is in axis2-kernel which Rampart depends
on. The upcoming Rampart 2.0.0 release (based on Axis2 2.0.1) will
inherit this fix automatically.
> Intermittent Rampart policy configuration missing Error
> -------------------------------------------------------
>
> Key: AXIS2-5904
> URL: https://issues.apache.org/jira/browse/AXIS2-5904
> Project: Axis2
> Issue Type: Bug
> Components: client-api, codegen, modules, rpc
> Affects Versions: 1.7.0, 1.7.7
> Environment: Apache Tomcat 9
> Reporter: Mohamed Anis Mekki
> Priority: Critical
> Fix For: 2.0.1
>
>
> I created a secured (sign body) Axis2 Web Service and generated .aar archive
> which I deployed to Axis2 Container (.war in Apache Tomcat). I then used
> Java2WSDL to generate a client stub. I finally created the class below that
> uses the client stub.
> In a nutshell the main method of the class calls consecutively the first then
> the second method of the service. I create a separate service stub for each
> call, using serviceStub() method and configure correctly the rampart security
> policy using getRampartConfig() method.
> {code:java}
> package tn.nat.cnss.client;
> import java.util.Properties;
> import java.rmi.RemoteException;
> import org.apache.axis2.AxisFault;
> import org.apache.axis2.context.ConfigurationContext;
> import org.apache.axis2.context.ConfigurationContextFactory;
> import org.apache.axis2.transport.http.HTTPConstants;
> import org.apache.neethi.Policy;
> import org.apache.rampart.policy.model.CryptoConfig;
> import org.apache.rampart.policy.model.RampartConfig;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ArrayOfString;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation1;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation2;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation1Response;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation2Response;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ServiceRequestOperation1;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ServiceRequestOperation2;
> public class Sample2SignBodyServiceClient
> {
> private static Policy getRampartConfig()
> {
> RampartConfig rampartConfig = new RampartConfig();
> rampartConfig.setUser("clientkey");
>
> rampartConfig.setPwCbClass("tn.nat.cnss.client.PasswordCallBackHandler");
> CryptoConfig sigCrypto = new CryptoConfig();
>
> sigCrypto.setProvider("org.apache.ws.security.components.crypto.Merlin");
> Properties props = new Properties();
>
> props.setProperty("org.apache.ws.security.crypto.merlin.keystore.type",
> "JKS");
>
> props.setProperty("org.apache.ws.security.crypto.merlin.file","keys/client.jks");
>
> props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password",
> "clientStorePW");
> sigCrypto.setProp(props);
> rampartConfig.setSigCryptoConfig(sigCrypto);
> Policy policy = new Policy();
> policy.addAssertion(rampartConfig);
> return policy;
> }
> private static Sample2SignBodyServiceStub serviceStub() throws AxisFault
> {
>
> org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
> ConfigurationContext ctx =
> ConfigurationContextFactory.createConfigurationContextFromFileSystem("client-repo",
> null);
> Sample2SignBodyServiceStub serviceStub = new
> Sample2SignBodyServiceStub(ctx,"http://localhost:8080/axis2/services/Sample2SignBodyService");
> serviceStub._getServiceClient().engageModule("rampart");
> Policy rampartConfig = getRampartConfig();
>
> serviceStub._getServiceClient().getAxisService().getPolicySubject().attachPolicy(rampartConfig);
>
> serviceStub._getServiceClient().getOptions().setTimeOutInMilliSeconds(300000);
>
> serviceStub._getServiceClient().getOptions().setProperty(HTTPConstants.SO_TIMEOUT,
> new Integer(300000));
>
> serviceStub._getServiceClient().getOptions().setProperty(HTTPConstants.CONNECTION_TIMEOUT,
> new Integer(300000));
> return serviceStub;
> }
> public static Operation1Response operation1(String...parameters) throws
> RemoteException, AxisFault
> {
> Sample2SignBodyServiceStub serviceStub = serviceStub();
> ServiceRequestOperation1 req = new ServiceRequestOperation1();
> req.setParam1(parameters[0]);
> req.setParam2(parameters[1]);
> req.setParam3(parameters[2]);
> Operation1 operation = new Operation1();
> operation.setServiceRequestOperation1(req);
> Operation1Response resp = serviceStub.operation1(operation);
> serviceStub._getServiceClient().cleanupTransport();
> serviceStub._getServiceClient().cleanup();
> serviceStub.cleanup();
> return resp;
> }
> public static Operation2Response operation2(String...parameters) throws
> RemoteException, AxisFault
> {
> Sample2SignBodyServiceStub serviceStub = serviceStub();
> ServiceRequestOperation2 req = new ServiceRequestOperation2();
> req.setParam1(parameters[0]);
> req.setParam2(parameters[1]);
> Operation2 operation = new Operation2();
> operation.setServiceRequestOperation2(req);
> Operation2Response resp = serviceStub.operation2(operation);
> serviceStub._getServiceClient().cleanupTransport();
> serviceStub._getServiceClient().cleanup();
> serviceStub.cleanup();
> return resp;
> }
> public static void main(String[] args) throws Exception
> {
> Operation1Response operation1Response = operation1("0",
> "99999", "99999");
> System.out.println("operation1: Debut Execution");
> System.out.println(operation1Response.get_return().getResult());
> System.out.println("Nombre de colonnes: " +
> operation1Response.get_return().getNumberColumns());
> System.out.println("Nombre de lignes: " +
> operation1Response.get_return().getNumberLines());
> for (ArrayOfString array :
> operation1Response.get_return().getDataSet())
> {
> for (String s : array.localArray)
> {
> System.out.print(s + "\t");
> }
> System.out.println();
> }
> System.out.println("operation1: Fin Execution");
> Operation2Response operation2Response = operation2("0",
> "99999");
> System.out.println("operation2: Debut Execution");
> System.out.println(operation2Response.get_return().getResult());
> System.out.println("Nombre de colonnes: " +
> operation2Response.get_return().getNumberColumns());
> System.out.println("Nombre de lignes: " +
> operation2Response.get_return().getNumberLines());
> for (ArrayOfString array :
> operation2Response.get_return().getDataSet())
> {
> for (String s : array.localArray)
> {
> System.out.print(s + "\t");
> }
> System.out.println();
> }
> System.out.println("operation2: Fin Execution");
> }
> }
> {code}
> The problem is that execution leads to the intermittent error below. By
> intermittent I mean that sometimes both operation calls execute properly, but
> some other times only the first call or none.
> {code:java}
> org.apache.axis2.AxisFault: Rampart policy configuration missing
> at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:76)
> at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:335)
> at org.apache.axis2.engine.Phase.invoke(Phase.java:308)
> at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:250)
> at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:415)
> at
> org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:399)
> at
> org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:225)
> at
> org.apache.axis2.client.OperationClient.execute(OperationClient.java:150)
> at
> tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLStub.operation2(Sample4SignEncryptBodyServiceSSLStub.java:307)
> at
> tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLClient.operation2(Sample4SignEncryptBodyServiceSSLClient.java:121)
> at
> tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLClient.main(Sample4SignEncryptBodyServiceSSLClient.java:162)
> Caused by: org.apache.rampart.RampartException: Rampart policy configuration
> missing
> at
> org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:277)
> at
> org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:250)
> at
> org.apache.rampart.builder.AsymmetricBindingBuilder.doSignature(AsymmetricBindingBuilder.java:760)
> at
> org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:417)
> at
> org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:88)
> at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147)
> at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:65)
> ... 10 more
> {code}
> I use Axis2 version 1.7.0 and Apache Tomcat 9.0 with Java 8.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]