クライアント・アプリケーションが Web サービスにアクセスできるようにクライアント証明書認証を構成
することができます。
始める前に
Web サービス・アクセスに対してクライアント証明書認証を使用可能にする
前に、以下の前提条件を満たす必要があります。
- プロバイダー用の自己署名された公開鍵と秘密鍵のペアを生成します。
keytool -genkey -alias default -keystore serverKey.jks -dname "CN=myServer, O=IBM, C=CN"
-storepass passw0rd -keypass passw0rd -storetype jks -validity 1000 -keyalg RSA
- default の証明書をエクスポートし、証明書をトラストストアにインポート
します。
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
- クライアント用の自己署名された公開鍵と秘密鍵のペアを 2 つ生成します。
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
- 2 つの別名の証明書をエクスポートし、トラストストアに証明書を
インポートします。
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
- ファイル serverKey.jks、serverTrust.jks、clientKey.jks、
および clientTrust.jks を ${server.config.dir}/resources/security ディレクトリーにコピーします。
注: keytool ユーティリティーは Java™ インストール・ディレクトリーに入っています。
このタスクについて
保護された Web サービス・リソースにアクセスする
ためにクライアント証明書認証と共に Web サービス・クライアント・アプリケーションを使用する必要がある場合、クライアントは、
有効な証明書を要求に含める必要があり、サービス・プロバイダーとの通信に HTTPS を使用する必要があります。
手順
- server.xml ファイルで jaxws-2.2、servlet-3.0 (または servlet-3.1)、および appSecurity-2.0 の各フィーチャーを有効にします。
<featureManager>
<feature>jaxws-2.2</feature>
<feature>servlet-3.0</feature>
<feature>appSecurity-2.0</feature>
</featureManager>
- server.xml ファイル内で SSL エレメントと、クライアントのカスタマイズされた SSL エレメント
を構成します。
<!-- 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" />
- server.xml ファイル内でログイン・レルムを構成し、
レルムをサービス・プロバイダーにバインドします。
<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>
- サービス・プロバイダーを構成します。
- Web サービスを作成します。
@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 {
...
}
- サービス・プロバイダー用の ibm-ws-bnd.xml ファイルを構成します。
<?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>
注: - ibm-ws-bnd.xml ファイルは、Web アプリケーションの /WEB-INF ディレクトリー
内にあるか、または、EJB ベースの Web サービス・アプリケーション (JAR アーカイブ) の /META-INF ディレクトリー
内になければなりません。
- ibm-ws-bnd.xml ファイル内の login-config エレメント
は、EJB ベースの Web サービス・アプリケーション (JAR アーカイブ) でのみ有効です。
Web アプリケーションの場合、login-config エレメント
は無視され、web.xml ファイル内の同じエレメントの値が
使用されます。
.
- Web サービス・エンドポイントを指定することによって、
サービス・クライアントを構成します。例えば、クライアント・アプリケーション
が TransportSecurityClient.war という名前の Web アプリケーションであるとします。
- クライアント・アプリケーションを server.xml ファイル内で構成します。
<application id="TransportSecurityClient" name="TransportSecurityClient"
location="TransportSecurityClient.war"
context-root="TransportSecurityClient" type="war" />
- クライアント・アプリケーション用の ibm-ws-bnd.xml ファイル
を構成します。
<?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>
- WSDL ロケーションを使用してクライアント・スタブを生成します。
@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
{...}
- @WebServiceRef アノテーションを
使用して、Web サービスをサーブレットに注入します。例えば、TestJaxWsTransportSecurityServlet などです。
@WebServiceRef(name = "service/SayHelloPojoService")
SayHelloPojoService pojoService;
@WebServiceRef(name = "service/SayHelloStatelessService")
SayHelloStatelessService statelessService;