You can configure client certificate authentication for your client applications to
access web services.
Before you begin
You must complete the following prerequisites before enabling client certificate authentication
for web services access:
- Generate a pair of self-signed public and private keys for
provider.
keytool -genkey -alias default -keystore serverKey.jks -dname "CN=myServer, O=IBM, C=CN"
-storepass passw0rd -keypass passw0rd -storetype jks -validity 1000 -keyalg RSA
- Export the certificate of the default and import the certificate into the trust
store.
keytool -export -alias default -file myserver.cer -keystore serverKey.jks
-storepass passw0rd -storetype jks
keytool -import -file myserver.cer -alias default -keystore clientTrust.jks
-storepass passw0rd -keypass passw0rd -storetype jks
- Generate two pairs of self-signed public and private for
client.
keytool -genkey -alias user0 -keystore clientKey.jks -dname "CN=employee0, O=IBM, C=CN"
-storepass passw0rd -keypass passw0rd -storetype jks -validity 1000 -keyalg RSA
keytool -genkey -alias admin0 -keystore clientKey.jks -dname "CN=manager0, O=IBM, C=CN"
-storepass passw0rd -keypass passw0rd -storetype jks -validity 1000 -keyalg RSA
- Export the certificates of the two alias and import the certificate into the trust
store.
keytool -export -alias user0 -file user0.cer -keystore clientKey.jks -storepass passw0rd -storetype jks
keytool -export -alias admin0 -file admin0.cer -keystore clientKey.jks -storepass passw0rd -storetype jks
keytool -import -file user0.cer -alias user0 -keystore serverTrust.jks -storepass passw0rd -keypass passw0rd -storetype jks
keytool -import -file admin0.cer -alias admin0 -keystore serverTrust.jks -storepass passw0rd -keypass passw0rd -storetype jks
- Copy the serverKey.jks, serverTrust.jks,
clientKey.jks, and clientTrust.jks files to the
${server.config.dir}/resources/security directory.
Note: The keytool utility can be found in your Java™ installation directory.
About this task
If you need to use the web service client application with the Client Certificate Authentication
to access the protected web service resources, the client must provide the valid certificate in the
request and must use the HTTPS to communicate with the service provider.
Procedure
- Enable the
jaxws-2.2
, servlet-3.0
(or
servlet-3.1
) and appSecurity-2.0
features in the
server.xml file.
<featureManager>
<feature>jaxws-2.2</feature>
<feature>servlet-3.0</feature>
<feature>appSecurity-2.0</feature>
</featureManager>
- Configure the SSL element and client customized SSL element in the
server.xml file.
<!-- Server SSL configuration -->
<ssl id="defaultSSLConfig" keyStoreRef="serverKeyStore" trustStoreRef="serverTrustStore"
clientAuthenticationSupported="true"/>
<keyStore id="serverKeyStore" location="serverKey.jks" type="JKS" password="passw0rd" />
<keyStore id="serverTrustStore" location="serverTrust.jks" type="JKS" password="passw0rd" />
<!-- customize SSL configuration -->
<ssl id="customizeSSLConfig" keyStoreRef="clientKeyStore" trustStoreRef="clientTrustStore" />
<keyStore id="clientKeyStore" location="clientKey.jks" type="JKS" password="passw0rd" />
<keyStore id="clientTrustStore" location="clientTrust.jks" type="JKS" password="passw0rd" />
- Configure the login realm in the server.xml file and bind the realm
to the service provider.
<application id="TransportSecurityProvider" name="TransportSecurityProvider"
location="TransportSecurityProvider.war" type="ear">
<application-bnd>
<security-role name="Employee">
<user name="employee0" />
<group name="employeeGroup" />
</security-role>
<security-role name="Manager">
<user name="manager0" />
</security-role>
<security-role name="AllAuthenticated">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
</application>
<basicRegistry id="basic" realm="BasicRealm">
<user name="employee0" password="emp0pwd" />
<user name="employee1" password="emp1pwd" />
<user name="manager0" password="mgr0pwd" />
<group name="employeeGroup">
<member name="employee0" />
<member name="employee1" />
</group>
</basicRegistry>
- Configure the service provider.
- Create web services.
@WebService(serviceName = "SayHelloPojoService",
portName = "SayHelloPojoPort")
public class SayHelloPojoService implements SayHelloService {
...
}
@WebService(serviceName = "SayHelloStatelessService",
portName = "SayHelloStatelessPort",
endpointInterface = "com.ibm.ws.jaxws.transport.server.security.SayHelloService")
@Stateless(name = "SayHelloSessionBean")
public class SayHelloStatelessService implements SayHelloLocal {
...
}
- Configure the ibm-ws-bnd.xml file for the service provider.
<?xml version="1.0" encoding="UTF-8"?>
<webservices-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ws-bnd_1_0.xsd"
version="1.0">
<http-publishing>
<webservice-security>
<security-constraint>
<web-resource-collection>
<web-resource-name>Only Managers</web-resource-name>
<url-pattern>/manager/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint id="AuthConstraint_manager">
<role-name>Manager</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Employees</web-resource-name>
<url-pattern>/employee/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint id="AuthConstraint_employee">
<role-name>Employee</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<!-- SECURITY ROLES -->
<security-role id="Staff">
<role-name>Employee</role-name>
<role-name>Manager</role-name>
</security-role>
<!-- AUTHENTICATION METHOD: client-cert authentication -->
<!-- login configuration -->
<login-config id="LoginConfig">
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Authentication</realm-name>
</login-config>
</webservice-security>
</http-publishing>
</webservices-bnd>
Note:
- The ibm-ws-bnd.xml file must be in the /WEB-INF
directory of a web application, or the /META-INF directory of an EJB-based web
service application (JAR archive).
- The
login-config
element in the ibm-ws-bnd.xml file takes
effect only in an EJB-based web service application (JAR archive). For a web application, the
login-config
element is ignored and the value of the same element in the
web.xml file is used.
.
- Configure the service client by specifying the web service endpoints. For example, the
client application is a web application named
TransportSecurityClient.war.
- Configure the client application in the server.xml file.
<application id="TransportSecurityClient" name="TransportSecurityClient"
location="TransportSecurityClient.war"
context-root="TransportSecurityClient" type="war" />
- Configure the ibm-ws-bnd.xml file for the client application.
<?xml version="1.0" encoding="UTF-8"?>
<webservices-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ws-bnd_1_0.xsd"
version="1.0">
<!-- POJO service reference binding-->
<service-ref name="service/SayHelloPojoService">
<port name="SayHelloPojoPort"
namespace="http://ibm.com/ws/jaxws/transport/security/"
ssl-ref="customizeSSLConfig"
key-alias="user0"/>
<properties http.conduit.tlsClientParameters.disableCNCheck="true" />
</service-ref>
<!-- Stateless service reference binding-->
<service-ref name="service/SayHelloStatelessService">
<port name="SayHelloStatelessPort"
namespace="http://ibm.com/ws/jaxws/transport/security/"
ssl-ref="customizeSSLConfig"
key-alias="user0"/>
<properties http.conduit.tlsClientParameters.disableCNCheck="true" />
</service-ref>
</webservices-bnd>
- Generate the client stubs through WSDL location.
@WebServiceClient(name = "SayHelloPojoService",
targetNamespace = "http://ibm.com/ws/jaxws/transport/security/",
wsdlLocation = "https://localhost:8020/TransportSecurityProvider/unauthorized/employPojoService?wsdl")
public class SayHelloPojoService
extends Service
{...}
@WebServiceClient(name = "SayHelloStatelessService",
targetNamespace = "http://ibm.com/ws/jaxws/transport/security/",
wsdlLocation = "https://localhost:8020/TransportSecurityProvider/unauthorized/EmployStatelessService?wsdl")
public class SayHelloStatelessService
extends Service
{...}
- Use the
@WebServiceRef
annotation to inject the web service into the
servlet. For example, the TestJaxWsTransportSecurityServlet
.
@WebServiceRef(name = "service/SayHelloPojoService")
SayHelloPojoService pojoService;
@WebServiceRef(name = "service/SayHelloStatelessService")
SayHelloStatelessService statelessService;