登录表单的定义:
登录的表单可能不仅仅限于用户名和密码,还可能附带别的一些验证信息,比如图形验证码,机器相关的识别码等.那么如果要附带这样信息,在CAS中如何实现.
下面将实现登录表单中增加图形验证码验证,机器码验证功能
表单Bean实现,实现org.jasig.cas.authentication.principal.Credentials接口,代码如下:
package com.soho.sso.caslogin;

import org.jasig.cas.authentication.principal.Credentials;


public class CasCredentials implements Credentials
{
private String jpegcode;

private String username;

private String password;

private String cpucode;

public String getCpucode()
{
return cpucode;
}


public void setCpucode(String cpucode)
{
this.cpucode = cpucode;
}


public final String getPassword()
{
return this.password;
}


public final void setPassword(final String password)
{
this.password = password;
}


public final String getUsername()
{
return this.username;
}


public final void setUsername(final String userName)
{
this.username = userName;
}


public String toString()
{
return this.username;
}


public String getJpegcode()
{
return jpegcode;
}


public void setJpegcode(String jpegcode)
{
this.jpegcode = jpegcode;
}


public boolean equals(final Object obj)
{

if (obj == null || !obj.getClass().equals(this.getClass()))
{
return false;
}

final CasCredentials c = (CasCredentials) obj;

return this.jpegcode.equals(c.getJpegcode()) && this.username.equals(c.getUsername())
&& this.password.equals(c.getPassword());
}


public int hashCode()
{
return this.jpegcode.hashCode() ^ this.username.hashCode() ^ this.password.hashCode();
}
}

表单验证类型,实现org.springframework.validation.Validator 接口:
package com.soho.sso.caslogin;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;


public class CasCredentialsValidator implements Validator
{


public boolean supports(Class arg0)
{
//对于表单Bean兼容的验证
return CasCredentials.class.isAssignableFrom(arg0);
}


public void validate(Object arg0, Errors errors)
{
//对于表单元素的验证
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username",
"required.username", null);
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
"required.password", null);

}

}

CAS 配置文件中\WEB-INF\cas-servlet.xml的定义BeanId处 authenticationViaFormAction变更上述实现类
<bean id="authenticationViaFormAction"
class="org.jasig.cas.web.flow.AuthenticationViaFormAction">
<property name="centralAuthenticationService" ref="centralAuthenticationService" />
<property name="warnCookieGenerator" ref="warnCookieGenerator" />
<property name="ticketGrantingTicketCookieGenerator" ref="ticketGrantingTicketCookieGenerator" />
<property name="formObjectName" value="credentials" />
<property name="formObjectClass" value="com.soho.sso.caslogin.CasCredentials" />
<property name="validator">
<bean
class="com.soho.sso.caslogin.CasCredentialsValidator" />
</property>
</bean>
上述的配置定义了CAS登录验证的自定义表单的实现.但是仍然没有对这些提交的表单数据实现验证逻辑.
CAS 登录验证工作流
CAS 3.1使用了spring的webflow来实现登录验证的步骤,那么就可以在webflow插入需要验证的环节!!!
验证码的验证Action,继承自 org.springframework.webflow.action.AbstractAction
package com.soho.sso.caslogin;

import org.springframework.webflow.Event;
import org.springframework.webflow.RequestContext;
import org.springframework.webflow.action.AbstractAction;

public class CaptchaValidateAction extends AbstractAction
{
@Override

protected Event doExecute(RequestContext context) throws Exception
{
System.out.println("图形验证!");
String jpegcode = (String)context.getRequestParameters().get("jpegcode");

if(jpegcode.equals(context.getExternalContext().getSessionMap().get("JPEGCODE")))
{
context.getExternalContext().getRequestMap().put("JPEGCODE_MSG", "");
return this.success();
}
context.getExternalContext().getRequestMap().put("JPEGCODE_MSG", "验证码错误!");
return this.error(new Exception("验证码错误!"));
}

}

机器码的验证Action:
package com.soho.sso.caslogin;

import org.springframework.webflow.Event;
import org.springframework.webflow.RequestContext;
import org.springframework.webflow.action.AbstractAction;

public class MacValidateAction extends AbstractAction
{
private CASDao casdao;

public CASDao getCasdao()
{
return casdao;
}

public void setCasdao(CASDao casdao)
{
this.casdao = casdao;
}
@Override

protected Event doExecute(RequestContext context) throws Exception
{
System.out.println("机器码验证!");
String macAddr = (String)context.getRequestParameters().get("macAddr");

if(macAddr==null || macAddr.trim().equals(""))
{
context.getExternalContext().getRequestMap().put("MACADDR_MSG", "机器验证码不能为空!");
return this.error(new Exception("机器码验证!"));
}

if(casdao.validateMacAddr(macAddr))
{
return this.success();
}
context.getExternalContext().getRequestMap().put("MACADDR_MSG", "机器码验证未通过!请检查机器码是否授权能访问系统?[" + macAddr + "]");
return this.error(new Exception("机器码验证!"));
}

}

用户登陆初始化Action:
package com.soho.sso.caslogin;

import org.springframework.webflow.Event;
import org.springframework.webflow.RequestContext;
import org.springframework.webflow.action.AbstractAction;

public class casInitUserInfoAction extends AbstractAction
{

@Override

protected Event doExecute(RequestContext context) throws Exception
{
System.out.println("用户初始化!");
context.getExternalContext().getSessionMap().put("USERCODE",(String)context.getRequestParameters().get("username"));
return this.success();
}

}

数据库操作支持:CASDao
package com.soho.sso.caslogin;

import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.lbxdrugs.sso.util.UtilMD5;


public class CASDao extends JdbcDaoSupport
{

public Map getUser(String usercode,String pwd) throws Exception
{

if(usercode==null || pwd==null || usercode.trim().equals("") || pwd.trim().equals(""))
{
throw new Exception("用户名或密码为空!");
}
String md5pass = UtilMD5.Crypt(pwd).toUpperCase();

Map user = this.getJdbcTemplate().queryForMap("SELECT * FROM T_CAS_USER WHERE USERCODE=?", new String[]
{usercode});

if(user==null || !user.get("PASSWORD").toString().toUpperCase().equals(md5pass))
{
throw new Exception("用户名或密码错误!");
}
return user;
}


public List queryUserAppList(Long userid)
{
List list = null;

try
{

list = this.getJdbcTemplate().queryForList("SELECT APPCODE,APPNAME,APP_HOMEPAGE,LOGON_USER,LOGON_PWD FROM T_CAS_APPUSERS T1 ,T_CAS_APP T2 WHERE T1.APPID=T2.APPID AND T1.USERID=?", new Long[]
{userid});

}catch(Exception e)
{
e.printStackTrace();
}
return list;
}

public List queryUserAppList(String username)
{
List list = null;

try
{
Long userid;

userid=this.getJdbcTemplate().queryForLong("select userid from t_cas_user where usercode=?",new String[]
{username});

list = this.getJdbcTemplate().queryForList("SELECT ROWNUM NUM,APPNAME,LOGON_USER,LOGON_PWD,APP_HOMEPAGE FROM T_CAS_APPUSERS T1, T_CAS_APP T2 WHERE T1.APPID(+) = T2.APPID AND T1.USERID(+)=?", new Long[]
{userid});

}catch(Exception e)
{
e.printStackTrace();
}
return list;
}

public boolean validateMacAddr(String mac)
{

Integer ct = this.getJdbcTemplate().queryForInt("select count(*) CT from t_license where trim(upper(CODE))=? and CHECKED=1", new String[]
{mac.toUpperCase()});

if(ct!=null && ct.intValue() == 1)
{
return true;
}
return false;
}
}

Spring对象配置:\WEB-INF\cas-servlet.xml 增加上述类的定义
<!-- 登录处理流增加的3个Action -->
<!-- 图形认证码认证 -->
<bean id="captchaValidateAction" class="com.soho.sso.caslogin.CaptchaValidateAction" />
<!-- MAC地址认证 -->
<bean id="macValidateAction" class="com.soho.sso.caslogin.MacValidateAction" >
<property name="casdao" ref="casdao" />
</bean>
<!-- 用户初始化 -->
<bean id="casInitUserInfoAction" class="com.soho.sso.caslogin.casInitUserInfoAction" />
数据库操作的DAO定义WEB-INF\applicationContext.xml
<bean id="casdao" class="com.soho.sso.caslogin.CASDao">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jdbc/ds</value>
</property>
</bean>
重要的一步,登录webflow的定义:WEB-INF\login-webflow.xml
<view-state id="viewLoginForm" view="casLoginView">
<transition on="submit" to="captchaValidate" /><!--转移图形验证处理-->
</view-state>
<!-- 图形验证 -->
<action-state id="captchaValidate">
<action bean="captchaValidateAction" />
<transition on="success" to="macValidate" /><!--机器码验证处理-->
<transition on="error" to="viewLoginForm" />
</action-state>
<!-- 机器码验证 -->
<action-state id="macValidate">
<action bean="macValidateAction" />
<transition on="success" to="bindAndValidate" />
<transition on="error" to="viewLoginForm" />
</action-state>
<action-state id="bindAndValidate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="submit" />
<transition on="error" to="viewLoginForm" />
</action-state>
<action-state id="submit">
<action bean="authenticationViaFormAction" method="submit" />
<transition on="warn" to="warn" />
<transition on="success" to="casInitUserInfo" /><!--插入初始化处理-->
<transition on="error" to="viewLoginForm" />
</action-state>
<!-- 初始化用户信息 -->
<action-state id="casInitUserInfo">
<action bean="casInitUserInfoAction" />
<transition on="success" to="sendTicketGrantingTicket" />
</action-state>
posted on 2009-04-21 11:55
弦惊塞外 阅读(864)
评论(2) 编辑 收藏