登錄表單的定義:
登錄的表單可能不僅僅限于用戶名和密碼,還可能附帶別的一些驗證信息,比如圖形驗證碼,機器相關的識別碼等.那么如果要附帶這樣信息,在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
弦驚塞外 閱讀(868)
評論(2) 編輯 收藏