Forum Discussion

dartmanx's avatar
dartmanx
New Contributor
5 years ago

Client Certificatates with DOD Common Access Cards

Has anyone successfully configured SOAP UI to use access an API with a DOD-issued common access card?

This is possible in ReadyAPI, but I have not been successful via SOAP UI, and not all of our developers have licenses for Ready API (and they will not be getting them either).

3 Replies

  • richie's avatar
    richie
    Community Hero
    Hey dartmanx

    I havent experience of DOD CACs, but im a Brit and that's a U.S. thing, right? But i'm wondering what the problem is with SoapUI. I use both ReadyAPI! and SoapUI and am struggling to identify why you cant get it working in SoapUI....do you use the licensed functionality im ReadyAPI! for your testing?

    Ta

    Rich
    • dartmanx's avatar
      dartmanx
      New Contributor

      The reason it works in ReadyAPI is because ReadyAPI provides a checkbox to use the Windows Certificate Store in the SSL preferences.

      I've spent hours trying to make SOAP UI work with only a keystore.jks with no success.

       

  • fig's avatar
    fig
    New Member

    Add as a groovy element: 

    import javax.net.ssl.*

    import java.security.KeyStore

    import java.net.URL

    import java.io.OutputStreamWriter

    // --- Step 1: Set up custom SSLContext from Windows-MY keystore ---

    KeyStore ks = KeyStore.getInstance("Windows-MY")

    ks.load(null, null)

    String aliasToUse = null

    def aliases = ks.aliases()

    while (aliases.hasMoreElements()) {

        def alias = aliases.nextElement()

        if (alias.toLowerCase().contains("authentication")) {

            aliasToUse = alias

            break

        }

    }

    if (aliasToUse == null) {

        throw new RuntimeException("No certificate with alias containing 'authentication' found.")

    }

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509")

    kmf.init(ks, null)

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509")

    tmf.init((KeyStore) null)

    SSLContext ctx = SSLContext.getInstance("TLS")

    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null)

    SSLContext.setDefault(ctx)

    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.socketFactory)

    log.info "Custom SSLContext initialized with alias: $aliasToUse"

    // --- Step 2: Build the SOAP request ---

    String soapBody = '''\

    <soapenv:Envelope>

       <soapenv:Header/>

       <soapenv:Body>

          <Request>

         </Request>

       </soapenv:Body>

    </soapenv:Envelope>

    '''

    // --- Step 3: Send the SOAP request ---

    def endpoint = "https://your-secure-api.example.com/endpoint" // Replace with actual endpoint

    def url = new URL(endpoint)

    def conn = (HttpsURLConnection) url.openConnection()

    conn.setRequestMethod("POST")

    conn.setDoOutput(true)

    conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8")

    conn.setRequestProperty("SOAPAction", "") // Optional, or set SOAPAction if required by server

    OutputStreamWriter writer = new OutputStreamWriter(conn.outputStream)

    writer.write(soapBody)

    writer.flush()

    writer.close()

    // --- Step 4: Read the response ---

    int responseCode = conn.getResponseCode()

    log.info "HTTP Response Code: $responseCode"

    def responseStream = responseCode >= 400 ? conn.getErrorStream() : conn.getInputStream()

    def responseText = responseStream?.getText('UTF-8') ?: "No response"

    log.info "SOAP Response:\n$responseText"