现在的位置: 首页 > 综合 > 正文

定制CAS登录验证

2012年10月06日 ⁄ 综合 ⁄ 共 5202字 ⁄ 字号 评论关闭


定制CAS登录验证

转载请保留作者信息:

作者:88250

Bloghttp:/blog.csdn.net/DL88250

MSN & Gmail &
QQ
DL88250@gmail.com

目录

摘要 1

环境 1

新建工程 1

添加依赖包 2

编写测试用例 2

编写实现代码 3

工程结构截图 5

测试与打包 5

启用定制后的登录验证 6

整合测试 7

总结 7

摘要

本文以LiferayCAS整合为例,将CAS登录验证从输入相同的用户名/密码定制为以Liferay的用户身份进行验证。

环境

在进行本文示例前,请参考这里

新建工程

打开NetBeans IDE,新建Java
Class Library工程:PortalAuthHandler

添加依赖包

CAS中的lib下找到如下jar

  • cas-server-core-3.3.jar

  • inspektr-core-0.7.0.jar

下载spring-core.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 <DL88250@gmail.com>

*/

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 <DL88250@gmail.com>

*/

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/cas-web/cas-server-core-3.3.jar中。

启用定制后的登录验证

编辑$LIFERAY_HOME/webapps/cas-web/WEB-INF/deployerConfigContext.xml文件,将

<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

替换为

<bean
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">

<property
name="sql" value="select password_ from User_ where
screenName=?"/>

<property
name="passwordEncoder" ref="base64PasswordEncoder"/>

<property
name="dataSource" ref="dataSource"/>

</bean>

注意:Liferay中最好使用screenName作为CAS验证的用户名,emailAddress是不能用的,ID方式没经过测试。

然后,在紧跟的

</list>

</property>

</bean>

后加入:

<bean
id="dataSource"

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property
name="driverClassName" value="${db.driver}" />

<property
name="url" value="${db.url}" />

<property
name="username" value="${db.username}" />

<property
name="password" value="${db.password}" />

</bean>


<bean
id="base64PasswordEncoder"

class="com.jinfonet.developer.portal.Base64PasswordEncoder"
autowire="byName">

<constructor-arg
value="SHA1" />

</bean>

最后,修改在文件$LIFERAY_HOME/webapps/cas-web/WEB-INF/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&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false

db.username=lportal

db.password=dl88250

整合测试

启动LiferayCAS后,登录Liferay(使用非Portlet)时将自动跳转到CAS验证页面,输入用户名(your
screen name)
与密码后,如果登录成功,将自动跳转到你在LiferayHome里。

总结

本文以CASLiferay的整合为例,介绍了定制CAS登录验证的整个开发与配置过程,也强调了一些需要注意的地方。使用CAS实现SSO(Single
Sign On)
将在下一次的文章中介绍,将以CAS整合Liferay+Scarab为例给大家介绍,请大家多多给予关注哦
: )

【上篇】
【下篇】

抱歉!评论已关闭.