1

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>
sys463
  • 337
  • 2
  • 5
  • 18

2 Answers2

1

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.

sys463
  • 337
  • 2
  • 5
  • 18
0

If you replace your current encryptionUser

<ramp:encryptionUser>server</ramp:encryptionUser>

with

<ramp:encryptionUser>useReqSigCert</ramp:encryptionUser>

Then the certificate used to sign the request message will be automatically used to encrypt the response message

Source

rekotc
  • 595
  • 1
  • 10
  • 21
  • 1
    Hi @rekotc, thanks for your answer. The usage of `useReqSigCert` does work for one server several clients approach. So when you set it to the server's `policy.xml` Rampart uses signature from client SOAP message to encrypt the response. But it does not work when you have several service instances (with several identity certificates) - at least I didn't get how to achieve that using configuration only :) – sys463 Jun 08 '21 at 15:20
  • Hi @sys463, you are right, i misunderstood your problem! Now i'd like to ask you a more detailed solution to your problem, as i might find myself in this situation... :D – rekotc Jun 10 '21 at 11:00
  • Hi @rekotc! I've updated the answer with some code examples. It's not ideal, but that's what I came to :) – sys463 Jun 10 '21 at 14:54