javasoapmutual-authenticationwss4jrampart

Apache Rampart WS-Security: one client, several service instances


I'm adding X.509 Mutual Certificate authentication into the project. The specific case here is that one client (let's say manager) can access several service instances (servers). Each server has its own certificate. When providing a policy.xml configuration on client side <encryptionUser> should be set to server's alias certificate stored in client's trustore. It's not a problem when the server is only one but when client need to access specific server, an appropriate server's public key should be used for encryption so I need to provide a proper alias from the truststore. I was thinking to programmarically change Rampart configuration on each request to set a specific alias name but this looks like not a proper way to do. I'm looking for a standard approach here or, perhaps, some way to configure that in policy.xml My client's (manager's) Rampart configuration part from policy.xml is below

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
   <ramp:userCertAlias>client</ramp:userCertAlias>
   <!-- This should be dynamic -->
   <ramp:encryptionUser>server</ramp:encryptionUser>
   <ramp:passwordCallbackClass>PasswordProvider</ramp:passwordCallbackClass>
   <ramp:signatureCrypto>
       <ramp:crypto provider="MerlinCrypto"/>
   </ramp:signatureCrypto>
   <ramp:encryptionCrypto>
       <ramp:crypto provider="MerlinCrypto"/>
   </ramp:encryptionCrypto>
</ramp:RampartConfig>

Solution

  • This problem was resolved by programmatically setting encryptionUser parameter to already parsed and built (from policy.xml) RampartConfig object inside Policy object. Build Policy object from configuration file, then go through the Assertions, find RamparConfig object among them and set the property.

    String encrUser = "myEncrUser";
    try (InputStream is = new FileInputStream("policy.xml")) {
        OMXMLParserWrapper omBuilder = OMXMLBuilderFactory.createOMBuilder(is);
        Policy policy = PolicyEngine.getPolicy(omBuilder.getDocumentElement());
        for (Iterator<List<Assertion>> assrItr = policy.getAlternatives(); assrItr.hasNext(); ) {
            List<Assertion> assr = assertionsIterator.next();
            assr.stream().filter(RampartConfig.class::isInstance)
                .findFirst().map(RampartConfig.class::cast)
                .ifPresent(cfg -> cfg.setEncryptionUser(encrUser));
        }
    } catch (IOException e) {
        // ...
    }
    

    Here a client application needs to have axis2 client object configured for each service but that was fine in my case.