定制 CAS 登录验证 转载请保留作者信息: 作者:88250 Blog:http:/blog.csdn.net/DL88250 MSN & Gmail & QQ:DL88250@gmail.com 目录 摘要.................................................................................................................................1 环境..................................................................................................................................................1 新建工程..........................................................................................................................................1 添加依赖包......................................................................................................................................2 编写测试用例..................................................................................................................................2 编写实现代码..................................................................................................................................3 工程结构截图..................................................................................................................................5 测试与打包......................................................................................................................................5 启用定制后的登录验证..................................................................................................................6 整合测试..........................................................................................................................................7 总结.................................................................................................................................7 摘要 本文以 Liferay 与 CAS 整合为例,将 CAS 登录验证从输入相同的用户名/密码定制为以 Liferay 的用户 身份进行验证。 环境 ● MySQL5.0.5 ● JRE 1.6.0.7 ● Ubuntu 8.04 ● Liferay 5.1.1 Bundled with Tomcat 6.0 ● CAS Server 3.3.1 ● Yale CAS Client 2.0.11 ● NetBeans IDE 6.1 在进行本文示例前,请参考这里。 新建工程 打开 NetBeans IDE,新建 Java Class Library 工程:PortalAuthHandler。 添加依赖包 从 CAS 中的 lib 下找到如下 jar: ● casservercore3.3.jar ● inspektrcore0.7.0.jar 下载 springcore.jar(2.5.5),点这里。 将这三个 jar 包添加到工程 PortalAuthHandler 下。 编写测试用例 在 Test Packages 下建立测试用例,代码如下: package com.jinfonet.developer.portal; import junit.framework.TestCase; import org.jasig.cas.authentication.handler.PasswordEncoder; /** * * @author 88250 */ public final class Base64PasswordEncoderTests extends TestCase { private final PasswordEncoder passwordEncoder = new Base64PasswordEncoder("SHA1"); public void testHashBase64Encoded() { assertEquals("qUqP5cyxm6YcTAhz05Hph5gvu9M=", this.passwordEncoder.encode("test")); } public void testNullPassword() { assertEquals(null, this.passwordEncoder.encode(null)); } public void testInvalidEncodingType() { final PasswordEncoder pe = new Base64PasswordEncoder("invalid encoding"); try { pe.encode("test"); fail("exception expected."); } catch (final Exception e) { return; } } } 这个测试用例有三个测试方法,其中 HashBase64Encoded 最为重要。因为在 Liferay 的帐户表 User_中 的 password_字段默认是以 SHA1 进行加密,然后再以 Base64 进行编码存放的。而 CAS 中自带的 Password Encoder 只有用加密算法进行加密的步骤,没有 Base64 编码的步骤,所以我们要写一个带有 Base64 编码功能的 Encoder ,且必须是实现 org.jasig.cas.authentication.handler.PasswordEncoder 接口的。 编写实现代码 package com.jinfonet.developer.portal; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.inspektr.common.ioc.annotation.NotNull; import org.jasig.cas.authentication.handler.PasswordEncoder; import org.springframework.util.StringUtils; import sun.misc.BASE64Encoder; /** * * @author 88250 */ public class Base64PasswordEncoder implements PasswordEncoder { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; @NotNull private final String encodingAlgorithm; private String characterEncoding; public Base64PasswordEncoder(final String encodingAlgorithm) { this.encodingAlgorithm = encodingAlgorithm; } public String encode(final String password) { if (password == null) { return null; } try { MessageDigest messageDigest = MessageDigest.getInstance(this.encodingAlgorithm); if (StringUtils.hasText(this.characterEncoding)) { messageDigest.update(password.getBytes(this.characterEncoding)); } else { messageDigest.update(password.getBytes()); } final byte[] digest = messageDigest.digest(); return getFormattedText(digest); } catch (final NoSuchAlgorithmException e) { throw new SecurityException(e); } catch (final UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * Takes the raw bytes from the digest and formats them correct. * * @param bytes the raw bytes from the digest. * @return the formatted bytes. */ private String getFormattedText(byte[] bytes) { final StringBuilder buf = new StringBuilder(bytes.length * 2); sun.misc.BASE64Encoder e = new BASE64Encoder(); final String buf2 = e.encode(bytes); for (int j = 0; j < bytes.length; j++) { buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); buf.append(HEX_DIGITS[bytes[j] & 0x0f]); } System.out.println("Final: " + buf2); System.out.println(encodingAlgorithm + ": " + buf); return buf2.toString(); } public final void setCharacterEncoding(final String characterEncoding) { this.characterEncoding = characterEncoding; } } 注意:这里,我们使用了 Sun 的一个受限类:BASE64Encoder。如果你自己有实现,尽量用自己的。 工程结构截图 工程的完整结构截图如下: 测试与打包 单元测通过后到工程目录下的 dist 目录下把 Build 出的 jar 中的 class 文件(with package)打包到 $LIFERAY_HOME/webapps/casweb/casservercore3.3.jar 中。 启用定制后的登录验证 编辑$LIFERAY_HOME/webapps/casweb/WEBINF/deployerConfigContext.xml 文件,将 替换为 注意:在 Liferay 中最好使用 screenName 作为 CAS 验证的用户名,emailAddress 是不能用的,ID 方式没经过测试。 然后,在紧跟的 后加入: 最后,修改在文件$LIFERAY_HOME/webapps/casweb/WEBINF/cas.properties 中配置一下数据 库连接,如下: #database.hibernate.dialect=org.hibernate.dialect.OracleDialect database.hibernate.dialect=org.hibernate.dialect.MySQLDialect #database.hibernate.dialect=org.hibernate.dialect.HSQLDialect db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/lportal? useUnicode=true&characterEncoding=UTF8&useFastDateParsing=false db.username=lportal db.password=dl88250 整合测试 启动 Liferay 与 CAS 后,登录 Liferay(使用非 Portlet)时将自动跳转到 CAS 验证页面,输入用 户名(your screen name)与密码后,如果登录成功,将自动跳转到你在 Liferay 的 Home 里。 总结 本文以 CAS 与 Liferay 的整合为例,介绍了定制 CAS 登录验证的整个开发与配置过程,也强调了一些需 要注意的地方。使用 CAS 实现 SSO(Single Sign On)将在下一次的文章中介绍,将以 CAS 整合 Liferay+Scarab 为例给大家介绍,请大家多多给予关注哦 : )