技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统架构 --> Apache + Jetty 架设 CAS 单点登录

Apache + Jetty 架设 CAS 单点登录

浏览:4228次  出处信息

最近一段时间一直在断断续续地尝试 CAS 单点登录的问题,一般的文章,都是直接使用 Tomcat 或者 Jetty 等 Java 应用服务器直接配置 SSL 并安装 CAS 的,但我不太想让 Java 服务器直接 binding 到 443 端口,因此就想仍然用 Apache 处理 SSL 请求,并转发给 Jetty。在这个过程中,主要尝试了以下个问题:

  1. 如何生成自签名的证书
  2. 如何配置 Apache
  3. 如何配置 Jetty
  4. 安装、测试 CAS
  5. 把自己的 CA 证书导入到 Java 的 cacerts 文件中并测试 CAS Proxy

整个过程在 Ubuntu 7.10 上完成,现记录如下。

1. 生成自签名的证书

通常要配置 https 的服务器,都需要一个由正式的 CA 机构认证的 X509 证书。当客户端连接 https 服务器时,会通过 CA 的共钥来检查这个证书的正确性。但要获得 CA 的证书是一件很麻烦的事情,而且还要花费一定的费用。因此通常一些小的机构会是使用自签名的证书。也就是自己做 CA,给自己的服务器证书签名。

这个过程有两个主要的步骤,首先是生成自己的 CA 证书,然后再生成各个服务器的证书并为它们签名。 我是用 OpenSSL 来生成自签名证书的。

第一步是制作 CA 的证书:

以下是引用片段:
openssl genrsa -des3 -out my-ca.key 2048

openssl req -new -x509 -days 3650 -key my-ca.key -out my-ca.crt

这会生成 my-ca.key 和 my-ca.crt 文件,前者存放着使用 my-ca.crt 制作签名时必须的密钥,应当妥善保管。而后者是可以公开的。上面的命令为 my-ca.key 设定的有效期为 10 年。

用命令

以下是引用片段:
openssl x509 -in my-ca.crt -text -noout

可以查看 my-ca.crt 文件的内容。

有了 CA 证书之后,就可以为自己的服务器生成证书了:

以下是引用片段:
openssl genrsa -des3 -out mars-server.key 1024

openssl req -new -key mars-server.key -out mars-server.csr

openssl x509 -req -in mars-server.csr -out mars-server.crt -sha1 -CA my-ca.crt -CAkey my-ca.key -CAcreateserial -days 3650

前两个命令会生成 key、csr 文件,最后一个命令则通过 my-ca.crt 为 mars-server.csr 制作了 x509 的签名证书。

需要注意的是,在执行上述第二个命令时,Common Name 选项应当输入的是服务器的域名,否则在用户通过 https 协议访问时每次都会有额外的提示信息。

用命令

以下是引用片段:
openssl x509 -in mars-server.crt -text -noout

可以查看 mars-server.crt 文件的内容。

2. 配置 Apache 服务器

首先,创建 /etc/apache2/ssl 目录,将刚刚制作的 my-ca.crt、mars-server.key 和 mars-server.crt 文件拷贝到这个目录中。

接着执行命令

以下是引用片段:
a2emod ssl

激活 Apache 的 SSL 模块,然后在 /etc/apache2/sites-enable/ 中添加虚拟主机,这个过程与添加普通的虚拟主机类似,不同点在于该主机的端口应为 443。配置如下:

以下是引用片段:
NameVirtualHost *:443
<VirtualHost *:443>
  ServerName localhost

  DocumentRoot /var/www

SSLEngine On

  SSLCipherSuite HIGH:MEDIUM

  SSLProtocol all -SSLv2

  SSLCertificateFile /etc/apache2/ssl/mars-server.crt

  SSLCertificateKeyFile /etc/apache2/ssl/mars-server.key

  SSLCACertificateFile /etc/apache2/ssl/my-ca.crt
  <Directory /var/www>
    Order deny,allow
    Allow from localhost

</Directory>

</VirtualHost>

<VirtualHost *:80>

ServerName localhost

  DocumentRoot /var/www

<Directory /var/www>    Order deny,allow

    Allow from localhost

</Directory>

</VirtualHost>

以上配置保证了用户在访问 443 和 80 端口时可以看到相同的内容,而仅仅是使用的协议不同。修改好配置后,便可以重启 Apache 服务器,这时需要输入 mars-server.key 的密码。用浏览器访问

以下是引用片段:
https://localhost/

这时应当看到一个弹出对话框,让你确认是否信任该站点的证书,选择信任后,便可以查看该站点的内容了。

由于大多数 Apache 服务器都是在服务器启动时自动启动,为了避免在启动 Apache 时输入密码,可以用以下命令生成不加密的 mars-server.key 文件:

以下是引用片段:
openssl rsa -in mars-server.key -out mars-server.key.insecure

用新生成的 mars-server.key.insecure 代替原有的 key 文件即可。

3. 配置 Jetty

Jetty 是一个很容易配置的 Java Servlet/JSP 服务器,下载解压后,用命令

以下是引用片段:
java -jar start.jar

即可执行。

由于我们希望通过 Apache 来访问 Jetty,就要激活 Jetty 对 AJP 的支持。可以用如下命令来启动服务器:

以下是引用片段:
java -jar start.jar etc/jetty.xml etc/jetty-ajp.xml

在 Apache 这一端,首先要安装 mod-jk 模块并激活它

以下是引用片段:
apt-get install libapache2-mod-jk

a2emod jk

其次要编写一个 /etc/apache2/worker.properties 文件,描述一下刚刚配置好的 jetty 服务器,文件内容如下:

以下是引用片段:
worker.list=jetty

worker.jetty.port=8009

worker.jetty.host=127.0.0.1

worker.jetty.type=ajp13

worker.jetty.lbfactor=1

接着要编写一个 /etc/apache2/mods-enabled/jk.conf 文件,内容如下:

以下是引用片段:
<IfModule mod_jk.c>
  JkWorkersFile "/etc/apache2/worker.properties"

  JkLogFile "/var/log/apache2/mod_jk.log"

  JkLogLevel info

  JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

  JkOptions +ForwardKeySize +ForwardURICompat
</IfModule>

最后,要修改刚刚的那个配置文件,让 mod_jk 来处理发送给 /cas/* 的请求,在虚拟主机的配置中加入如下命令:

以下是引用片段:
JkMount /cas/* jetty

4. 安装、测试 CAS

下载 CAS 3.x,并将 /modules/cas-server-webapp-*.war 文件复制到 jetty 的 webapps 目录下,改名为 cas.war。

此时通过浏览器访问 https://localhost/cas/ 便可看到 CAS 的界面了。我们是使用 LDAP 服务器来存储用户信息的,关于 CAS 的定制问题,稍后在其它的文章中再阐述。

我是通过 phpCAS 来对 CAS 服务器进行测试的,首先下载 phpCAS-0.6*、解压到 /var/www/phpcas 目录中。

安装 php-curl 和 php-pear,并通过 pear 安装 PEAR::DB。

以下是引用片段:
pear install DB

将 phpcas/docs/examples/ 中的文件复制到 phpcas/sources/ 目录中,修改这些文件中相关的 URL 信息,并用浏览器访问 example_simple.php,便可看到 CAS 的登录界面了。输入用户名密码后,应当可以看到登录成功的信息。

5. 将 my-ca.crt 导入到 Java 的 cacerts 文件中,并测试 CAS Proxy

CAS Proxy 的作用是让一个 CAS 的应用可以通过 CAS 来访问另一个 CAS 应用,而不需要用户多次提供密码。在这种情况下,CAS 会通过 https 访问每个 CAS 应用。由于我们的 CA 证书是自己制作的,它并不存在于 Java 的根证书列表中,这就导致 CAS 无法正常地连接我们的 https 服务器从而导致 CAS Proxy 功能不可用。要解决这个问题,必须将 my-ca.crt 文件导入到 Java 的根证书列表中。

我尝试了用 Java 提供的 keytool 来处理这个问题,但它总是要求输入 cacerts 文件的密码,而我根本没有这个密码。后来尝试用 IBM 的 keyman 解决了这个问题。keyman 是一个 GUI 程序,下载后用它来编辑 /etc/java-6-sun/security/cacerts 文件即可。注意导入密钥时,应选则 trustcacerts。

导入该密钥后,重启 Jetty 服务器,再访问 example_proxy.php 文件便可得到正确的结果了。

参考文献:

1. Van’s Apache SSL/TLS mini-HOWTO
2. Creating a self-signed SSL certificate
3. How to configure Apache SSL
4. Apache AJP13, mod_jk and mod_proxy_ajp
5. IBM KeyMan

建议继续学习:

  1. Netty和Jetty的Java NIO 网络框架模型分析    (阅读:4486)
  2. 互联网上的单点登录研究    (阅读:4061)
  3. Jetty线程“互锁”导致数据传输性能降低问题分析    (阅读:2917)
  4. 【译】无附加模块实现Drupal的多子域名下的单点登录    (阅读:2629)
  5. 关于 Jetty Continuation    (阅读:2504)
  6. Jetty 8长连接上的又一个坑    (阅读:1424)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1