Mutual Authentication for Web Services: A Live Example
By Mark Basler and Marina Sum, October 24, 2005
Secure communications among Web services are a must for supply-chain applications. Adventure Builder is a set of applications that showcases Web services on the Java 2 Platform, Enterprise Edition (J2EE 1.4 platform). The Order Processing Center of Adventure Builder must communicate securely with external entities, for example, to exchange purchase orders and invoices. While designing Adventure Builder, the BluePrints team opted for secure, mutually authenticated Web services for such communication. Why? Because the primary goal is to achieve the most secure interoperability among the modules and the participants.
This paper describes that implementation procedure for mutual authentication, step by step, and offers debugging tips.
By way of background, Adventure Builder was first developed at Sun as a reference application and then moved to java.net as part of the open-source project blueprints.dev.java.net under the subproject adventurebuilder . That application was also a topic of a popular book, Designing Web Services With the J2EE 1.4 Platform , available for free download in PDF.
Overview of Mutual Authentication
With mutual authentication, you trust the actual entity's certificate or an entity in the certificate chain, which implies that you trust its descendant. For example, in hiring a building contractor, you'd opt for someone who previously did a commendable job for a friend. Since your friend trusted and recommended that contractor highly, you automatically trust that person, too, because you trust your friend.
Certificate and certificate chain trust work in like manner. Your friend acts as a link in the certificate chain. You trust the client certificate and directly import the certificate into your truststore, where all the trusted certificates reside. Alternatively, you trust a third-party certificate authority, such as VeriSign, which implies trust in the certificates that VeriSign distributes or signs.
For more information on Web-service security, see Chapter 7, "Security," in the book Designing Web Services with the J2EE 1.4 Platform . To learn about certificates, see the section, " Understanding Digital Certificates," in the J2EE 1.4 Tutorial.
When you send messages with mutual authentication, a connection is possible only if the client trusts the server's certificate and the server trusts the client's certificate. The process of exchanging certificates and setting up connection properties is called the Secure Sockets Layer (SSL) handshake. For details, see the section, " SSL Protocol Overview," in the Java Secure Socket Extension (JSSE) Reference Guide.
While creating a domain, an application server, such as Sun Java System Application Server Platform Edition 8.1 (henceforth, Application Server), generates a default, self-signed certificate. That certificate, which contains an alias of s1as, is stored in the domain's keystore at App_Server_install_dir /domains/domain_name/config/keystore.jks. Application Server also imports the s1as certificate into the domain's truststore at App_Server_install_dir /domains/domain_name/config/cacerts.jks. For interoperability, the default truststore contains numerous preinstalled VeriSign certificates.
Implementation
Follow the two procedures described in this section to implement mutual authentication for Adventure Builder.
Exchanging Digital Certificates Among Participants
When deploying Adventure Builder with the default options on Application Server, you deploy the Order Processing Center and the Supply Chain vendor modules on the same instance of Application Server. That is, you use the same s1as certificate for the client and the server certificates. Since Application Server also imports the s1as certificate into the domain's truststore, it enables the mutually authenticated connection.
In a real-world scenario, the Order Processing Center and the Supply Chain vendors would be located on different machines across the Internet. To enable the connections, Application Server must import the client and server certificates into their counterparts' truststores.
To export a certificate from a keystore and import it into the counterpart's truststore, perform the steps below. Bear in mind the following:
- Application Server exports the certificate in
domain1from its keystore intodomain2's truststore. - The default password for Application Server for accessing the keystore or truststore is
changeit.
- List the keystore contents in
domain1. Type (all on one line):$JAVA_HOME/bin/keytool -list -keystoreApp_Server_install_dir/domains/domain1/config/keystore.jks - Type
changeitat the password prompt. Here is at the password prompt. Here is the output. output.Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry s1as, Aug 9, 2005, keyEntry, Certificate fingerprint (MD5): 9F:A1:F1:F9:3C:CB:60:B0:64:F1:35:F7:01:57:3B:0A - Export the
domain1certificate from its keystore. Type (all on one line):$JAVA_HOME/bin/keytool -export -alias s1as -file /tmp/domain1_s1as.cer -keystoreApp_Server_install_dir/domains/domain1/config/keystore.jks - Type
changeitat the password prompt. Here is the output.Certificate stored in file <\tmp\domain1_s1as.cer> - Import the exported certificate into the
domain2truststore. Type (all on one line):$JAVA_HOME/bin/keytool -import -trustcacerts -alias domain1_s1as -file /tmp/domain1_s1as.cer -keystoreApp_Server_install_dir/domains/domain1/config/cacerts.jks - Type
changeitat the password prompt. Here is the output.Owner: CN=baslerxp.sfbay.sun.com, OU=Sun Java System Application Server, O=Sun Microsystems, L=Santa Clara, ST=California, C=US Issuer: CN=baslerxp.sfbay.sun.com, OU=Sun Java System Application Server, O=Sun Microsystems, L=Santa Clara, ST=California, C=US Serial number: 42f9160f Valid from: Tue Aug 09 13:46:07 PDT 2005 until: Fri Aug 07 13:46:07 PDT 2015 Certificate fingerprints: MD5: 9F:A1:F1:F9:3C:CB:60:B0:64:F1:35:F7:01:57:3B:0A SHA1: B6:1E:6C:CC:20:B0:2E:CB:87:F2:3C:DE:53:FD:08:E9:92:BC:69:90 Trust this certificate? [no]: y Certificate was added to keystore - List the
domain2truststore to verify the import. Type (all on one line):$JAVA_HOME/bin/keytool -list -keystoreApp_Server_install_dir/domains/domain1/config/cacerts.jks - Type
changeitat the password prompt. Here is the output.TheKeystore type: jks Keystore provider: SUN Your keystore contains 14 entries verisignc1g3, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): B1:47:BC:18:57:D1:18:A0:78:2D:EC:71:E8:2A:95:73 verisignc1g2, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): DB:23:3D:F9:69:FA:4B:B9:95:80:44:73:5E:7D:41:83 verisignc1g1, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): 97:60:E8:57:5F:D3:50:47:E5:43:0C:94:36:8A:B0:62 verisignc2g3, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): F8:BE:C4:63:22:C9:A8:46:74:8B:B8:1D:1E:4A:2B:F6 verisignc2g2, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): 2D:BB:E5:25:D3:D1:65:82:3A:B7:0E:FA:E6:EB:E2:E1 domain1_s1as, Aug 16, 2005, trustedCertEntry, Certificate fingerprint (MD5):9F:A1:F1:F9:3C:CB:60:B0:64:F1:35:F7:01:57:3B:0A verisignc2g1, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): B3:9C:25:B1:C3:2E:32:53:80:15:30:9D:4D:02:77:3E verisignc3g3, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): CD:68:B6:A7:C7:C4:CE:75:E0:1D:4F:57:44:61:92:09 verisignc3g2, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9 domain2, Aug 10, 2005, trustedCertEntry, Certificate fingerprint (MD5): 23:47:42:EF:48:CB:29:FA:09:DC:C6:C3:C0:D4:D3:59 verisignc3g1, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): 10:FC:63:5D:F6:26:3E:0D:F3:25:BE:5F:79:CD:67:67 mykey, Aug 9, 2005, trustedCertEntry, Certificate fingerprint (MD5): A0:AF:EC:4A:4F:4A:54:FA:AE:7C:D9:3C:7F:2F:FE:3A s1as, Aug 5, 2005, trustedCertEntry, Certificate fingerprint (MD5): 9F:A1:F1:F9:3C:CB:60:B0:64:F1:35:F7:01:57:5C:3D verisignsecureserver, Apr 8, 2004, trustedCertEntry, Certificate fingerprint (MD5): 74:7B:82:03:43:F0:00:9E:6B:B3:EC:47:BF:85:A5:93domain1certificate is now trusted bydomain2. To havedomain1trustdomain2, rerun the procedure, that is, export fromdomain2and import intodomain1.For details on the Java 5 Standard Edition Key and Certificate Management Tool (keytool), see its documentation.
Configuring Endpoint Deployment Descriptors
The method for configuring the components depends on how you implemented the Web service, as follows:
- If you implemented the Web service with a Web module, you must revise the
web.xmldeployment descriptor. - If you implemented the Web service with an EJB component, you must revise the
sun-ejb-jar.xmldeployment descriptor for that specific component.
This section describes the changes required for the deployment descriptors for both implementations.
Web Module Implementation
To enable mutual authentication for a Web module, add a security constraint to the web.xml deployment descriptor to target the URL pattern and the manner in which the constraint applies. The code snippet below, which originates from the J2EE 1.4 Tutorial, targets the /hello URL pattern and requires a CONFIDENTIAL transport with a CLIENT-CERT authentication mechanism.
<security-constraint>
<display-name>SecurityConstraint</display-name>
<web-resource-collection>
<web-resource-name>WRCollection</web-resource-name>
<url-pattern>/hello</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
For details, see the section, " Example: Client-Certificate Authentication over HTTP/SSL with JAX-RPC," in the J2EE 1.4 Tutorial.
The values for the boldfaced elements are as follows:
-
transport-guaranteeIdentifies the type of transport between the client and the server. You specify one of three case-sensitive values:-
NONERequires no transport guarantees. -
INTEGRALSends the data between the client and the server in such a manner as to ensure that the data are uneditable. -
CONFIDENTIALSends the data between the client and server in such a manner as to ensure that the true contents are unreadable.
-
-
auth-methodIdentifies the authentication mechanism for the Web module. You specify one of four case-sensitive values:-
BASICUses basic authentication, that is, a user ID and password. -
DIGESTUses basic authentication (a user ID and password) but sends the password in encrypted format. -
FORMAuthenticates by presenting a Web Page for input. -
CLIENT-CERTAuthenticates with a client certificate.
-
EJB Module Implementation
To enable mutual authentication for an EJB module that exposes only a Web-service endpoint, you must set the auth-method element to CLIENT-CERT and the transport-guarantee element to CONFIDENTIAL. The code snippet below is an example from Adventure Builder. The full text of the deployment descriptor is in the Adventure_Builder_Install /project/apps/activitysupplier/activitysupplier-ejb/src/conf/sun-ejb-jar.xml file.
<ejb>
<ejb-name>ActivityPOEndpointBean</ejb-name>
...
<webservice-endpoint>
<port-component-name>ActivityPOIntfPort</port-component-name>
<endpoint-address-uri>webservice/ActivityPOService</endpointaddress-uri>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</webservice-endpoint>
</ejb>
The values for the boldfaced elements are as follows:
-
auth-methodIdentifies the authentication mechanism for the EJB Webservice endpoint. You specify one of two case-sensitive values:-
BASICUses basic authentication, that is, a user ID and password. -
CLIENT-CERTAuthenticates with a client certificate.
-
-
transport-guaranteeIdentifies the type of transport to use between the client and the server. You specify one of three case-sensitive values:-
NONERequires no transport guarantees. -
INTEGRALSends the data between the client and the server in such a manner as to ensure that the data are uneditable. -
CONFIDENTIALSends the data between the client and server in such a manner as to ensure that the true contents are unreadable.
-
Mutual authentication for an EJB module that also exposes the EJB component through remote or local interfaces requires one more level of security: the ior-security-constraint element. Add that element to the sun-ejb-jar.xml deployment descriptor to specify that confidentiality and client trust are required, as follows.
...
<ior-security-config>
<transport-config>
<integrity>REQUIRED</integrity>
<confidentiality>REQUIRED</confidentiality> <establish-trust-in-target>SUPPORTED</establish-trust-in-target> <establish-trust-in-client>REQUIRED</establish-trust-in-client>
</transport-config>
</ior-security-config>
...
Note: If the EJB module is exposed only through a Web-service endpoint or if you do not desire this constraint for the EJB module's remote or local interfaces, omit this step.
Here are what the constraint elements mean:
-
integrityDetermines whether the EJB module enforces that the message contents are editable. You specify one of three values:NONE,SUPPORTED, orREQUIRED. -
confidentialityDetermines whether the EJB module enforces that the message contents are readable. You specify one of three values:NONE,SUPPORTED, orREQUIRED. -
establish-trust-in-targetDetermines whether the server should authenticate itself to the client for this EJB module. You specify one of two values:NONEorSUPPORTED. -
establish-trust-in-clientDetermines whether the client should authenticate itself to the server for this EJB module. You specify one of three values:NONE,SUPPORTED, orREQUIRED.
Here are what the values mean:
-
NONEThe constraint is not used. -
SUPPORTEDThe constraint is supported but not required. -
REQUIREDThe constraint is required.
Debugging Tips
To ease the debugging process, from the administration GUI, update the Java virtual machine options for the server's configuration and set a system property to display different levels of logging. The most common level is -Djavax.net.debug=ssl:handshake. For details on the procedure and on the java.net.debug system property, see the section, " Debugging Utilities," in the Java Secure Socket Extension (JSSE) Reference Guide.
Also, if the client's keystore contains multiple private keys, the private key's certificate with the latest timestamp serves as the client certificate that authenticates to the server. In that case, it might be problematic to pinpoint the correct client certificate to import into the server's truststore. As a resolution, import all the certificates into the client's keystore. The keystore in the normal production configuration contains only one private key that represents the client, however.
References
- Sun Java System Application Server
- Java Secure Socket Extension (JSSE) Reference Guide
- J2EE 1.4 Tutorial
- Java Web Services Tutorial