IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere | Open source | Security  >

在 WebSphere Application Server Community Edition 中使用数字证书进行客户机身份验证

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

Vamsavardhana Reddy Chillakuru, 顾问软件工程师, IBM 

2007 年 7 月 09 日

通过本文了解设置 IBM® WebSphere® Application Server Community Edition 来基于数字证书对 Web 客户机进行身份验证和授权所需的知识和如何进行此工作。另外,还将了解当使用证书实现安全性的声明和编程时如何开发和部署 Web 应用程序。

引言

Web 服务器通常使用数字证书为使用 HTTPS(而不是 HTTP 协议)的 Web 客户机进行服务器身份验证,以访问该服务器上运行的应用程序。不过,对于客户机身份验证,数字证书的方式并不经常使用;更为常见的是,客户机使用用户名和密码之类的元素进行身份验证。 从服务器的角度而言,这两个身份验证方法都可以,但通过 HTTPS 使用用户名和密码进行身份验证仍然有潜在的危险,因为密码可能会丢失、被盗或以其他方式遭到破坏。使用证书的客户机身份验证可以帮助克服凭据被破坏的问题,从而让您对应用程序的安全性更加有信心。

本文描述对使用数字证书进行客户机身份验证的需求以及对在 IBM WebSphere Application Server Community Edition 中部署的 Web 应用程序中进行身份验证和授权决策的需求。本文将重点讨论管理控制台提供的私钥和证书管理功能,并将提供 Web 应用程序示例,以演示如何通过使用数字证书的客户机身份验证实现 Web 应用程序安全性的声明和编程实现。

本文需要使用 WebSphere Application Server Community Edition Version 1.0.1 或更高版本。





回页首


关于数字证书

数字证书最常见的用途是验证发送消息的用户是其声明的用户,并向接收方提供对应答进行编码的方法。此功能用于在 HTTPS 协议(基于 SSL)上对 Web 服务器和客户机进行身份验证。希望发送加密消息的实体将创建公钥-私钥对,并从证书颁发机构(Certificate Authority,CA)申请数字证书。CA 发出经过加密的数字证书,其中包含应用程序的公钥和各种其他身份标识信息。CA 通过公开输出的方式提供自己的公钥。使用最广泛的数字证书标准是 X.509。





回页首


使用管理控制台

管理控制台提供了一种方便而友好的方式来管理 WebSphere Application Server Community Edition(以下称为 Community Edition)的诸多方面。管理控制台的功能将不断改进和发展,目前提供了多个 Portlet 来执行各种管理任务,如 KeyStore、Web Server、Applications 和 Security Realms Portlet,我们将在本文中使用这些 Portlet。管理控制台还提供了让管理员查看和监视服务器状态的 Portlet,如 Information、JVM 和 DB Info Portlet。启动 Community Edition 后,就可以通过 http://localhost:8080/console 访问管理控制台。默认的登录名为 system,其密码为 manager

KeyStore Portlet

管理控制台中的 KeyStore Portlet JKS 类型 Java™ 密钥存储库文件进行操作,此文件在 Community Edition 中预先配置为指向 server 目录下的 var/security/keystore 文件。 此 Portlet 允许您进行以下操作:

  • 在安装期间自动启用管理安全性。
  • 查看密钥存储库内容。
  • 生成 RSA 密钥对(密钥长度为 512、1024 和 2048 位)。
  • 生成证书签名请求(Certificate Signing Request,CSR)。
  • 导入受信任的证书。
  • 删除受信任的证书。
  • 导入 CA 应答。
  • 删除私钥。

这些操作是密钥管理不可或缺的一部分。(Community Edition 用户并不需要 keytool 一类的密钥管理工具。)密钥存储库中的私钥和受信任证书可以用于为 Web 容器配置 HTTPS 侦听器。在本文中,我们将使用 KeyStore Portlet 来进行以下工作:

  • 删除现有密钥对。
  • 生成新密钥对。
  • 生成 CSR。
  • 导入受信任证书。
  • 导入 CA 应答。

要在 Community Edition 中启动 KeyStore Portlet,请在 Console Navigation 部分的 Security 标题下选择 Keystore 链接(图 1)。要查看任意私钥或受信任证书条目的详细信息,请单击对应别名提供的 view 链接,KeyStore Portlet 将随后显示条目详细信息。


图 1. 管理控制台:KeyStore Portlet
图 1. 管理控制台:KeyStore Portlet

Web Server Portlet

Web Server Portlet 允许管理员启动/停止/删除 Web 容器可用的各种网络侦听器。另外还能通过其添加新 HTTP、HTTPS 和 AJP 网络侦听器。在本文中,我们将使用 Web Server Portlet 来进行以下工作:

  • 添加新 HTTPS 侦听器。
  • 停止和启动现有网络侦听器。

要启动 Web Server Portlet,请在 Console Navigation 部分的 Server 标题下选择 Web Server 链接(图 1)。

Security Realms Portlet

通过 Security Realms Portlet,管理员库添加新的安全领域和编辑现有安全领域。该 Portlet 还提供了用法链接,可提供有关如何配置应用程序来针对安全领域进行身份验证的信息。在本文中,我们将使用 Security Realms Portlet 来添加新的证书属性文件域。要启动 Security Realms Portlet,请在 Console Navigation 部分的 Security 标题下单击 Security Realms 链接(图 1)。

应用程序相关 Portlet

提供了多个应用程序相关 Portlet,管理员可通过其将新 Web 应用程序、EJB 组件、J2EE 应用程序、应用程序客户机、J2EE 连接器等部署到 Community Edition。这些 Portlet 还支持启动、停止和卸载现有应用程序、连接器等。我们将使用 Deploy New Applications Portlet 来部署示例应用程序。要启动 Portlet,请在 Console Navigation 部分的 Applications 标题下选择 Deploy New 链接(图 1)。





回页首


设置密钥存储库

随 Community Edition 提供的缺省密钥存储库 (<base-dir>/var/security/keystore) 包含别名为“geronimo”的密钥对和别名为“geronimoca”的受信任证书。除非在服务器安装之后删除此缺省密钥对并生成新密钥对,否则将使用多个其他 Community Edition 服务器安装使用的密钥。在此部分,我们将描述使用 KeyStore Portlet 设置密钥存储库的过程,以便将其用于配置 HTTPS 侦听器。

生成密钥对

要生成新密钥对,请启动 KeyStore Portlet 并单击 generate keypair 链接(图 1)。将随即显示一个表单,可以在其中为要生成的密钥对输入详细信息(图 2)。密钥配置字段的定义如下。


图 2. 生成密钥对
图 2. 生成密钥对
  • Alias:用于在密钥存储库中标识此密钥对的名称。此名称应该与密钥存储库中的现有条目的别名不同。在我们的示例中,我们使用“mybizzzkeys”作为别名,而没有使用两个现有别名“geronimo”和“geronimoca”。

  • Key Algorithm:用于生成密钥对的私钥算法。管理控制台仅支持“RSA”。

  • Key Size:RSA 密钥的模块的长度,以位为单位。密钥越长,密钥对越安全。管理控制台支持的密钥长度为 512、1024 和 2048。在我们的示例中,我们使用 1024 的长度。(有关 RSA 密钥的建议密钥长度,请参见参考资料。)

  • Signature Algorithm:用于对自签名证书(作为“生成密钥对”练习的一部分生成)进行签名的签名算法。管理控制台支持 MD2withRSA、MD5withRSA 和 SHA1withRSA 签名算法。在我们的示例中,我们使用 MD5withRSA。

  • Validity:指示密钥对的有效期,用天数表示。在我们的示例中,使用的有效期值为 365。

  • Common Name (CN):承载 Web 应用程序的 Web 服务器的 DNS 名称,它要对 Web 客户机的服务器进行身份验证。例如,如果应用程序要驻留在 www.mybizzz.com 上,则使用与之相同的名称作为公用名,这样客户机就可以使用 http://www.mybizzz.com 或 https://www.mybizzz.com 来访问该应用程序。在我们的示例中,我们使用“localhost”作为公用名。

  • Organizational Unit (OU)/Organizational Name (O)/Locality (L)/State (ST):完成这些字段来反映请求者的身份。

  • Country (C):请求者所在国家的双字母 ISO 3166 国家代码。在我们的示例中,我们使用的是 IN,它是印度的国家代码。

提交表单后,KeyStore Portlet 将生成新 RSA 密钥对和自签署证书,并将密钥对添加到密钥存储库中。要查看新添加的条目的详细信息,请单击针对相应别名(此处为 mybizzzkeys)提供的 view 链接(图 1)。图 3 显示了这个新生成的密钥对的详细信息。


图 3. 私钥详细信息
图 3. 私钥详细信息

生成 CSR

要从证书颁发机构 (CA) 获取数字证书,需要从密钥对生成证书签名请求(Certificate Signing Request,CSR),并将其发送到 CA。要生成任何私钥条目的 CSR,请首先在 KeyStore Portlet 中查看条目详细信息(图 3)。选择了 generate CSR 链接后,KeyStore Portlet 将生成 PKCS10 证书请求,并将其显示在文本区域,以便将文本复制粘贴到文本文件中。清单 1 显示了我们示例中生成的 CSR。


清单 1 证书签名请求
                
-----BEGIN CERTIFICATE REQUEST-----
MIIBtjCCAR8CAQAweDESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQLEwlXZWIgU2FsZX
MxFjAUBgNVBAoTDU15IEJpenp6IEluYy4xFjAUBgNVBAcTDVNvbWUgTG9jYWxpdHkxETAP
BgNVBAgTCE15IFN0YXRlMQswCQYDVQQGEwJJTjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgY
kCgYEAj7Tvpnvu+FUAEqJym3d3iQEG7KmgebBCdN+eKOwjogS4jtwtqwhi7NhAwwby6guv
GT2cBZTngwnMhW3kFez/M5IP/65jqXdMAvRmwG+xbxYzXB7DE62koBA09pUXGlf4nVRJ21
14kN0A9UHGn4v9Zei9TcsesV9DxUFCftvDrWUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQB+
ybUf8dPfC9YzAZcLfJ7ZbswNsfdRnLisec8AdyDPnINMw3la4S+JC690vLlTUrmM13rKvG
+nUEPLjF8GkOb344zrgHymLVkhpFw6kahWcnwjmHbJvA3lw/nvZDGwEFsM5OpuhhBV5rAQ
qE7g+Q86sYWamu87C44MNGgpY3eXKg==
-----END CERTIFICATE REQUEST-----

导入 CA 应答

接收到 CSR 后,CA 将验证 CSR 中的信息的有效性,并颁发证书。CA 发出的应答通常采用 PKCS7 编码文本格式,其中包含经过 CA 签名的客户机证书,还可能包含链接到根 CA 的其他证书。对于本文,“My Own Root CA”(自有 CA)发出的 CA 应答(清单 2)仅包含单个证书。


清单 2. “My Own Root CA”发出的 CA 应答
                
-----BEGIN CERTIFICATE-----
MIICdzCCAeCgAwIBAgIDAK2cMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYDVQQGEwJJTjEQMA4GA1UE
ERMHWklQQ09ERTERMA8GA1UECBMITXkgU3RhdGUxFDASBgNVBAcTC015IExvY2FsaXR5MQ8wDQYD
VQQKEwZNeSBPcmcxFDASBgNVBAsTC015IE9yZyBVbml0MRcwFQYDVQQDEw5NeSBPd24gUm9vdCBD
QTAeFw0wNTEyMzExODMwMDBaFw0wNjEyMzExODMwMDBaMHgxEjAQBgNVBAMTCWxvY2FsaG9zdDES
MBAGA1UECxMJV2ViIFNhbGVzMRYwFAYDVQQKEw1NeSBCaXp6eiBJbmMuMRYwFAYDVQQHEw1Tb21l
IExvY2FsaXR5MREwDwYDVQQIEwhNeSBTdGF0ZTELMAkGA1UEBhMCSU4wgZ8wDQYJKoZIhvcNAQEB
BQADgY0AMIGJAoGBAI+076Z77vhVABKicpt3d4kBBuypoHmwQnTfnijsI6IEuI7cLasIYuzYQMMG
8uoLrxk9nAWU54MJzIVt5BXs/zOSD/+uY6l3TAL0ZsBvsW8WM1wewxOtpKAQNPaVFxpX+J1USdtd
eJDdAPVBxp+L/WXovU3LHrFfQ8VBQn7bw61lAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEALh/KMUYS
/xFG/hu0/EtLJIKuUwUUowTmO8VzV/Tdl+IMKr/NLpnqQLM0eM+6Q+144k5PLS4J7ovXJUTYFh59
TKtXNI/1GhBpIJ20NNgzqSkRJcKnv+PGKzXM45C2ojvN1cYeUvdGSpWdw+fZ/UrDw9nbg8HwwaQL
2/wLWjYUmHs=
-----END CERTIFICATE-----

此处给出 CA 应答仅针对我们示例的证书请求。按照本文所述生成的任何证书请求的 CA 应答都将与此不同。要导入清单 2 中所示的 CA 应答,请使用下载文件中提供的 keystore.new 文件覆盖“var/security/keystore”,然后重新启动 Community Edition 服务器。

导入 CA 应答:

  1. 在 KeyStore Portlet 中查看“mybizzzkeys”的详细信息(图 3)。

  2. 单击 import CA reply 链接,并将 CA 应答文本文件的内容粘贴到 PKCS7 Certificate Reply 标题下的文本区域中。

  3. 单击 Save 按钮。

现在密钥存储库已经准备好,可供 Community Edition 用于通过新获得的证书进行 Web 服务器身份验证。


图 4. 已导入的 CA 应答
图 4. 已导入的 CA 应答

删除缺省密钥

缺省密钥存储库包含别名为“geronimo”的私钥。启动缺省 HTTPS 侦听器需要使用此私钥。使用 KeyStore Portlet 生成新密钥对后,就不再需要缺省私钥了。由于密钥存储库中没有提供相应的功能来指定 HTTPS 侦听器使用的私钥的别名,因此应该将缺省私钥条目从密钥存储库中删除。

要删除缺省私钥条目,请执行以下步骤:

  1. 单击针对别名“geronimo”提供的 view 链接(图 1)。

  2. 单击 Delete Entry 链接(图 3)并确认条目删除。

  3. 确认后,将从密钥存储库删除缺省私钥条目。密钥存储库中现有单个私钥,其别名为“mybizzzkeys”。任何使用 var/security/keystore 文件的 HTTPS 侦听器现在都将使用此私钥进行服务器身份验证。

将 CA 证书作为受信任证书导入

为了启用 HTTPS 上的客户机身份验证,需要将 CA 证书作为受信任证书导入到密钥存储库中。将 CA 证书作为受信任证书导入后,将接受该 CA 发出的所有证书进行客户机身份验证。在我们的示例应用程序中,我们使用“My Own Root CA”发出的客户机证书。为了确保 HTTPS 侦听器接受此 CA 发出的证书,需要将 CA 的证书(清单 3)作为受信任证书导入到密钥存储库中。


清单 3. “My Own Root CA”的证书
                
-----BEGIN CERTIFICATE-----
MIIChjCCAe+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCSU4xEDAOBgNVBBET
B1pJUENPREUxETAPBgNVBAgTCE15IFN0YXRlMRQwEgYDVQQHEwtNeSBMb2NhbGl0eTEPMA0GA1UE
ChMGTXkgT3JnMRQwEgYDVQQLEwtNeSBPcmcgVW5pdDEXMBUGA1UEAxMOTXkgT3duIFJvb3QgQ0Ew
HhcNMDUxMjMxMTgzMDAwWhcNMTkxMjMxMTgzMDAwWjCBiDELMAkGA1UEBhMCSU4xEDAOBgNVBBET
B1pJUENPREUxETAPBgNVBAgTCE15IFN0YXRlMRQwEgYDVQQHEwtNeSBMb2NhbGl0eTEPMA0GA1UE
ChMGTXkgT3JnMRQwEgYDVQQLEwtNeSBPcmcgVW5pdDEXMBUGA1UEAxMOTXkgT3duIFJvb3QgQ0Ew
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOGfnakKJlSw5daLSYAo3dpAqk/HAz9LX0zFZiIi
8m6HiPaiWdkYVoA3WxLzrrzqRDFlDhZUHIRE+nBz/C/DyGkJm3qRT6EJt/h8IPizN2tgcbHEWtmo
GvaYoFMcQ8gjPeDPqSMB36ALH8zdlswZ/t0wR/TogCijVEUnQ+1ERmNHAgMBAAEwDQYJKoZIhvcN
AQEFBQADgYEAOb/KlJK2nQ5VTgC/wZ3G+3Ft4gRNv8iazjRs0N3CX/zAMGxV1ECkveLunBrCn/SN
Mqq9WMVvzJtDbcxU1cE75Ncng893QlfnboShpVsXeH6gTT5saCsIeoD+VoqBaktuS6QuSN1JUz+i
NSr1SNzbyoZiPq/UgexQMxFqowA3PDI=
-----END CERTIFICATE-----

导入受信任证书:

  1. 在 KeyStore Portlet 中单击 import trusted certificate(图 1)。

  2. 选择包含 CA 的证书的文件或输入文件名,并单击 View Certificate 按钮。(在我们的示例中,CA 证书位于文本文件 myownrootca-cert.txt 中,在下载文件中提供了此文件。)

  3. 为此受信任证书输入别名,并单击 Import 按钮(图 5)完成导入。(所使用的别名应该与密钥存储库中的现有条目的别名不同。)


图 5. “My Own Root CA”证书详细信息
图 5. “My Own Root CA”证书详细信息




回页首


具有客户机身份验证功能的 HTTPS 侦听器

端口 8443 上的缺省 HTTPS 侦听器未启用客户机身份验证。此 HTTPS 侦听器配置为使用 var/security/keystore。前面部分的密钥存储库更新通过 KeyStore Portlet 应用后,此 HTTPS 侦听器将使用新添加的私钥进行服务器身份验证。为了验证这一点,请通过 Web server Portlet 停止并启动缺省 HTTPS 侦听器,然后访问 URL https://localhost:8443/。(访问此 URL 前,必须将 CA 证书安装到 Web 浏览器中,以避免出现任何警告消息。)加载了页面后,双击浏览器任务栏上的 lock 图标,并单击 view 按钮来查看证书详细信息(图 6)。验证该证书的确是“My Own Root CA”颁发的。在我们的示例中,我们使用了 Mozilla Firefox Web 浏览器。


图 6. 在浏览器中查看服务器证书详细信息
图 6. 在浏览器中查看服务器证书详细信息

添加具有客户机身份验证功能的 HTTPS 侦听器

将需要启用了客户机身份验证的 HTTPS 侦听器,以配置 Web 应用程序使用数字证书进行客户机身份验证。在此部分,我们将了解如何使用 Web Server Portlet 添加新 HTTPS 侦听器以及各个参数的含义。

添加新 HTTPS 侦听器:

  1. 启动 Web Server Portlet 并选择 Add new HTTPS Listener for Tomcat 链接。

  2. 为所有适用参数输入值,并单击 Save 按钮(图 7)。这将添加并启动新 HTTPS 侦听器。

主要参数的描述如下。


图 7. HTTPS 侦听器参数
图 7. HTTPS 侦听器参数
  • Host:端口绑定到的主机名称或 IP 地址。我们在示例中使用的是 0.0.0.0。

  • Port:要绑定的网络端口。在我们的示例中,我们使用 443,即 HTTPS 的缺省端口。

  • Keystore File:保存密钥存储库的文件。KeyStore Portlet 预配置为指向 Community Edition 安装目录下的 var/security/keystore。本文前面生成的密钥对已由 KeyStore Portlet 添加到此文件中,因此我们将在此字段中使用 var/security/keystore。

  • Keystore Password:用于访问密钥存储库文件和私钥项的密码。KeyStore Portlet 配置为使用密码 secret

  • Keystore Type:Keystore File 字段项的密钥存储库类型var/security/keystore 的密钥存储库类型为“JKS”。

  • Truststore File:保存信任存储区的文件。在我们的示例中,将受信任证书添加到 var/security/keystore,其本身将充当信任存储区。因此,我们将为此字段使用 var/security/keystore

  • Truststore Password:用于验证 Truststore File 字段的密码,在我们的示例中,它是 var/security/keystore 的密码(即 secret

  • Truststore Type:Truststore File 字段项的密钥存储库类型。在我们的示例中,所用的值为“JKS”。

  • HTTPS Algorithm:HTTPS Algorithm 提供程序。通常应将其设置为与 JVM 供应商匹配。在此字段中使用“JVM Default”,这样当服务器运行在与所选值不同的 JVM 上时,不需要重新配置 HTTPS 侦听器。在我们的示例中,我们为此参数使用“JVM Default”。

  • HTTPS Protocol:这应该通常设置为 TLS,不过除非更改为 SSL,否则某些 JVM 就不能与流行的浏览器一起正常使用。在我们的示例中,我们为此参数使用“SSL”。

  • Client Auth Required:在我们的示例中,我们将此字段设置为要求进行客户机身份验证。如果设置了此字段,则通过此连接器连接的客户机必须提供有效的客户机证书。将使用存储在以下位置的第一个 CA 证书检查有效性:

    1. 上面配置的信任存储库。
    2. javax.net.ssl.trustStore 系统属性指定的密钥存储库文件。
    3. java-home/lib/security/jssecacerts。
    4. java-home/lib/security/cacerts。

    由于我们已经配置了信任存储库,因此将只接受存储库中由这些 CA 颁发的证书进行客户机身份验证。

验证具有客户机身份验证功能的 HTTPS 侦听器

要验证新添加的 HTTPS 侦听器是否正常工作,请访问 URL https://localhost/。由于浏览器中没有任何受信任 CA 颁发的客户机证书,这将导致出现错误,网页无法访问。

现在,将私钥和 webclient01.p12 文件中提供的“My Own Root CA”颁发的客户机证书导入到 Web 浏览器中,然后再次访问 URL https://localhost/。这次由于浏览器具有信任存储库中的 CA 颁发的证书,浏览器将显示一个对话框(图 8),让您选择用于对 Web 服务器进行身份验证的证书。选择了客户机证书后,服务器将对客户机进行身份验证,然后就可以访问网页了。


图 8. 选择用于进行身份验证的客户机证书
图 8. 选择用于进行身份验证的客户机证书




回页首


添加安全领域实现声明安全性

Web 服务器配置为使用具有客户机身份验证功能的 HTTPS 侦听器后,就可以添加证书属性文件领域;Web 应用程序可以随后配置为针对此领域进行身份验证。此部分描述可以如何将此类安全领域添加到 Community Edition。

属性文件

证书属性文件领域使用两个属性文件参数配置:用户文件和组文件。下面显示了用户文件(清单 4)和组文件(清单 5)的示例。这些文件基于 webclient01.p12、webclient02.p12、webclient11.p12 和 webclient12.p12 中提供的客户机证书(可从下载文件部分获得),应该将这些文件导入 Web 浏览器,以便使用示例应用程序。


清单 4. var/security/cert-users.properties
                
webclient01=CN=Web Client01,OU=Org Unit0,O=Org0,L=Loc0,ST=St0,C=IN
webclient02=CN=Web Client02,OU=Org Unit0,O=Org0,L=Loc0,ST=St0,C=IN
webclient11=CN=Web Client11,OU=Org Unit1,O=Org1,L=Loc1,ST=St1,C=US
webclient12=CN=Web Client12,OU=Org Unit1,O=Org1,L=Loc1,ST=St1,C=US

在 cert-users.properties 文件中,客户机证书的 X509Certificate.getSubjectX500Principal().getName() 映射到一个用户名。


清单 5. var/security/cert-groups.properties
                
admin=webclient01,webclient02
guest=webclient11,webclient12

在 cert-groups.properties 文件中,会将 cert-users.properties 文件中的用户名映射到组。将这两个属性文件保存到 <base-dir>/var/security 目录中。

添加证书属性文件领域

要添加证书属性文件领域:

  1. 启动 Security Realms Portlet 并选择 add new security realm 链接。
  2. 输入安全领域的名称(我们使用 cert-prop-file-realm)。
  3. 对于 Realm Type,选择 Certificate Properties File Realm,然后单击 Next。
  4. 输入用户文件的 URI(即 var/security/cert-users.properties)和组文件的 URI(即 var/security/cert-groups.properties)。单击 Next
  5. 单击 Skip Test and Deploy 按钮,以添加领域。

现在可以将添加的领域用于配置 Web 应用程序安全性。当客户机使用有效客户机证书(即与 cert-users.properties 中的 X500Principal 匹配)针对此领域进行安全验证时,领域将返回带 GeronimoUserPrincipal 和 GeronimoGroupPrincipal 的主题。





回页首


示例应用程序

将 CA 证书和客户机证书安装到 Web 浏览器中

要使用示例应用程序,应该将下载文件中提供的 CA 证书和客户机证书安装到 Web 浏览器(将负责管理受信任 CA 和客户机证书)中。浏览器还将提供证书安装功能。例如,Mozilla Firefox 提供了证书管理器 (Certificate Manager),可以通过单击 Certificates => Advanced 部分下的 Manage Certificates 按钮启动。

安装 CA 证书

大部分 Web 浏览器都提供了知名 CA 的预安装证书,如 Verisign、Equifax 等。通过这样,具有这些 CA 所颁发的任意网站都可以方便地通过验证,从而通过浏览器进行访问。对于我们的演示,我们使用自有根 CA“My Own Root CA”颁发的服务器和客户机证书。在通过 HTTPS 访问使用此 CA 颁发的证书的网站时,如果尚未在浏览器中安装此 CA 的证书(在下载文件中提供),浏览器将显示一个警告消息(类似于“Web Site Certified by an Unknown Authority”之类),并提供访问或拒绝网站所提供的证书的选项。如果在浏览器中安装了 CA 的证书,则将不会显示此警告消息。

在 Mozilla Firefox 中,可以使用 Certificate Manager => Authorties 部分下的 Import 选项安装 CA 的证书。

安装客户机证书

示例应用程序需要 Web 浏览器使用数字证书进行身份验证。下载文件中提供了四个 PKCS12 密钥存储库文件,每个文件包含一个密钥对和一个“My Own Root CA”颁发的证书。安装之后,这些客户机证书就可以用于针对将“My Own Root CA”指定为可信任的 Web 服务器(在我们的示例中为 localhost)进行身份验证。在 Mozilla Firefox 中,可以使用 Certificate Manager 部分的 Your Certificates 选项卡下提供的 Import 选项进行客户机证书安装。

使用声明安全性的示例应用程序

本文到目前为止已建立了使用证书进行客户机身份验证所需的基础设施。现在我们将了解如何配置应用程序来使用客户机身份验证。

演示声明安全性的示例应用程序将使用我们在前面添加的安全领域。此应用程序包含受保护的 Web 资源,采用三种不同的 URL 模式:保护 (protect)、访客 (guest) 和禁止 (forbidden)。web.xml 应用程序部署描述符的相关部分显示在清单 6 中。(下载文件中提供了完整的 cert-realm-sample-web.xml 文件。)


清单 6. 声明安全性示例:web.xml
                
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" ...>
    ...
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>Admin Role</web-resource-name>
        <url-pattern>/protect/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
        <role-name>content-administrator</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>No Access</web-resource-name>
        <url-pattern>/forbidden/*</url-pattern>
      </web-resource-collection>
      <auth-constraint/>
      ...
    </security-constraint>
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>Guest</web-resource-name>
        <url-pattern>/guest/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
        <role-name>guest-user</role-name>
      </auth-constraint>
      ...
    </security-constraint>

    <login-config>
      <auth-method>CLIENT-CERT</auth-method>
      <realm-name>Not Required for CLIENT-CERT</realm-name>
    </login-config>

  <security-role> <role-name>content-administrator</role-name> </security-role>
  <security-role> <role-name>guest-user</role-name> </security-role>
</web-app>

此应用程序使用两个用户角色:content-administrator 和 guest-user。请注意,auth-method 设置为 CLIENT-CERT,以便能将应用程序配置文件针对“Certificate Properties File Realm”进行身份验证。请注意 transportation-guarantee 约束设置为 CONFIDENTIAL。这就允许 Web 服务器在使用 HTTP 访问受保护资源时将请求转发到 HTTPS 端口。

此示例应用程序的应用程序部署计划的相关部分显示在清单 7 中。(下载文件中提供了完整的 cert-realm-sample-plan.xml 文件。)


清单 7. 声明安全性示例:部署计划
                
<?xml version="1.0" encoding="UTF-8"?>
<web-app configId="cert-realm-sample" ... >
  <context-root>/cert-realm-sample</context-root>
  ...
  <security-realm-name>cert-prop-file-realm</security-realm-name>
  <security>
    <default-principal realm-name="cert-prop-file-realm">
      <principal class="org.apache.geronimo.security.realm.providers.
	GeronimoUserPrincipal" 
	name="webclient01"/>
	<!-- name should match the entries from cert-users.properties of the realm -->
    </default-principal>
    <role-mappings>
      <role role-name="content-administrator">
        <realm realm-name="cert-prop-file-realm">
          <principal class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
		name="admin" designated-run-as="true"/>  
		<!-- name should match the entries from cert-groups.properties of the realm -->
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|

          <principal class="org.apache.geronimo.security.realm.providers.
		GeronimoUserPrincipal" name="webclient01"/>
          ...
        </realm>
      </role>
      <role role-name="guest-user">
        <realm realm-name="cert-prop-file-realm">
          <principal class="..." name="guest" designated-run-as="true"/>
          ...
        </realm>
      </role>
    </role-mappings>
  </security>
</web-app>

请注意,此计划中的 security-realm-name 为“cert-prop-file-realm”,是我们前面刚添加的。部署计划中的角色应该与 web.xml Web 部署描述符中的角色匹配。

此应用程序打包为 WAR 文件,即 cert-realm-sample.war,可从下载文件中获取。可以使用 Applications Portlet 或命令行部署程序来部署此应用程序。部署并启动应用程序后,可在以下位置访问该应用程序:http://localhost:8080/cert-realm-sample/。

使用编程安全性的示例应用程序

演示编程安全性的示例应用程序包含名为 AuthorizationServlet 的 Servlet。如果 Web 客户机使用证书进行客户机身份验证,Servlet 容器将在名为“javax.servlet.request.X509Certificate”的请求属性中向 Servlet 提供证书链。AuthorizationServlet 通过调用 request.getAttribute() 方法检索证书链,此方法将返回由证书对象组成的数组。数组中的第一个元素与客户机证书对应。随后可以由 Servlet 对证书进行处理,从而基于证书字段做出授权决策。在此示例中,AuthorizationServlet 检索和显示各个证书字段,并使用 MyX509Name 类处理证书名称字段。AuthorizationServlet.java 的相关部分显示在清单 8 中。(下载文件中提供了完整的 AuthorizationServlet.java 文件。)


清单 8. AuthorizationServlet.java
                
public class AuthorizationServlet extends HttpServlet implements Servlet {
	
	public static final String SSL_CERT = "javax.servlet.request.X509Certificate";

	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
	   throws ServletException, IOException {
		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();

		java.security.cert.X509Certificate[] certs = (java.security.cert.X509Certificate[]) 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
			request.getAttribute(SSL_CERT);
		if(certs == null) {
			out.println("Client did not use a certificate for authentication");
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
			return;
		}
		MyX509Name sname = new MyX509Name(certs[0].getSubjectX500Principal().getName());
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
		out.println("Welcome "+sname.getCommonName()+"!!");
		out.println();
		out.println("You have been authenticated using a digital certificate");
		// Display certificate fields.  The field values can be checked to make authorization
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
		decisions.
		out.println("Cert S.No. : "+certs[0].getSerialNumber());
		out.println();
		out.println("Subject Info:");
		out.println("Common Name: " + sname.getCommonName());
		out.println("Org Unit: " + sname.getOrganizationalUnit());
		out.println("Org: " + sname.getOrganization());
		out.println("Locality: " + sname.getLocality());
		out.println("State: " + sname.getState());
		out.println("Country: "+ sname.getCountry());
		out.println();

		MyX509Name iname = new MyX509Name(certs[0].getIssuerX500Principal().getName());
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
		out.println("Issuer Info:");
		out.println("Common Name: " + iname.getCommonName());
             ...
	}
...
}

此示例应用程序的 web.xml 部署描述符如清单 9 中所示。


清单 9. 编程安全性示例:web.xml
                
<?xml version="1.0" encoding="UTF-8"?>

<web-app id="cert-auth-sample" 
   xmlns="http://java.sun.com/xml/ns/j2ee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   version="2.4">

   <display-name>cert-auth-sample</display-name>
   <distributable/>

   <welcome-file-list>
     <welcome-file>index.html</welcome-file> 
   </welcome-file-list>
   <servlet>
      <display-name>AuthorizationServlet</display-name>
      <servlet-name>AuthorizationServlet</servlet-name>
      <servlet-class>clientauth.AuthorizationServlet</servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>AuthorizationServlet</servlet-name>
      <url-pattern>/secure/AuthorizationServlet</url-pattern>
   </servlet-mapping>

   <security-constraint>
     <web-resource-collection>
       <web-resource-name>Secure</web-resource-name>
       <url-pattern>/secure/AuthorizationServlet</url-pattern>
     </web-resource-collection>
     <user-data-constraint>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </user-data-constraint>
   </security-constraint>
</web-app>

请注意 transportation-guarantee 约束设置为 CONFIDENTIAL。这就允许 Web 服务器在使用 HTTP 访问受保护资源时将请求转发到 HTTPS 端口。

此应用程序打包为 WAR 文件,即 cert-auth-sample.war,可从下载文件中获取。可以使用 Deploy New Applications Portlet 或命令行部署程序来部署此应用程序。部署并启动应用程序后,可在以下位置访问该应用程序:http://localhost:8080/cert-auth-sample/。





回页首


结束语

IBM WebSphere Application Server Community Edition v1.0.1 及更高版本可以配置为使用数字证书在 Web 应用程序中进行客户机身份验证。本文演示了如何完成此工作,并说明了可以如何使用管理控制台进行密钥管理,如生成密钥对、导入 CA 应答和受信任证书等。通过示例应用程序,我们还了解了如何配置 Web 应用程序来实现使用证书进行客户机身份验证的声明安全性和编程安全性。






回页首


下载

描述名字大小下载方法
Client authentication code samplessamples.zip173 KBHTTP
关于下载方法的信息


参考资料

学习

获得产品和技术


关于作者

Author photo

Vamsavardhana Reddy Chillakuru是位于印度班加罗尔的 IBM India Software Labs 的一名顾问软件工程师。他在 Apache Geronimo 和 WebSphere Application Server Community Edition 的支持团队工作。您可以通过 vamsic007@in.ibm.com 与 Vamsi 联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款