CAS增加驗證碼
1.1開始增加驗證碼
package org.chengli.cas.credential;
import org.jasig.cas.authentication.UsernamePasswordCredential;
public class CustomUsernamePasswordCredential extends
UsernamePasswordCredential {
private static final long serialVersionUID = 5034129937759981063L;
private String captcha;
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
}
修改前:
<var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential" />
修改後:
<var name="credential" class="org.chengli.cas.credential.CustomUsernamePasswordCredential" />
修改前:
<view-state id="viewLoginForm" view="casLoginView" model="credential">
<binder>
<binding property="username" />
<binding property="password" />
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credential'" />
</on-entry>
<transition on="submit" bind="true" validate="true" to="realSubmit">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />
</transition>
</view-state>
修改後:
<view-state id="viewLoginForm" view="casLoginView" model="credential">
<binder>
<binding property="username" />
<binding property="password" />
<binding property="captcha" />
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credential'" />
</on-entry>
<transition on="submit" bind="true" validate="true" to="customValidator">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />
</transition>
</view-state>
(3)在login-webflow.xm增加l配置
<action-state id="customValidator">
<evaluate expression="authenticationViaFormAction.customValidator(flowRequestContext, flowScope.credential, messageContext)"></evaluate>
<transition on="error" to="generateLoginTicket" />
<transition on="success" to="realSubmit" />
</action-state>
修改前:
<bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"
p:centralAuthenticationService-ref="centralAuthenticationService"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketRegistry-ref="ticketRegistry"/>
修改後:
<bean id="authenticationViaFormAction" class="org.chengli.cas.validator.CustomAuthenticationViaFormAction"
p:centralAuthenticationService-ref="centralAuthenticationService"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketRegistry-ref="ticketRegistry"/>
(5)新建包:org.chengli.cas.validator,新建類:CustomAuthenticationViaFormAction並繼承AuthenticationViaFormAction,增加方法:customValidator,
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
package org.chengli.cas.validator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.chengli.cas.credential.CustomUsernamePasswordCredential;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.web.flow.AuthenticationViaFormAction;
import org.jasig.cas.web.support.WebUtils;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import com.google.code.kaptcha.Constants;
public class CustomAuthenticationViaFormAction extends
AuthenticationViaFormAction {
public final Event customValidator(RequestContext context,
Credential credential, MessageContext messageContext) {
HttpServletRequest request = WebUtils.getHttpServletRequest(context);
HttpSession session = request.getSession();
String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
session.removeAttribute(Constants.KAPTCHA_SESSION_KEY);
CustomUsernamePasswordCredential cuCredential = (CustomUsernamePasswordCredential) credential;
String submitCaptcha= cuCredential.getCaptcha();
if (!StringUtils.hasText(submitCaptcha)) {
messageContext.addMessage(new MessageBuilder().error().code("login.required.captcha").build());
return new Event(this, ERROR);
}
if (submitCaptcha.equals(captcha)) {
return new Event(this, SUCCESS);
}
messageContext.addMessage(new MessageBuilder().error().code("login.captcha.error").build());
return new Event(this, ERROR);
}
}
(6)CAS實現了國際化支持,錯誤信息都放在國際化文件中,在messages.properties、messages_zh_CN.properties加入以下內容:
login.captcha.error=驗證碼錯誤
<servlet>
<servlet-name>Kaptcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<init-param>
<param-name>kaptcha.image.width</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.length</param-name>
<param-value>4</param-value>
</init-param>
<init-param>
<param-name>kaptcha.noise.impl</param-name>
<param-value>com.google.code.kaptcha.impl.NoNoise</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
(8)在登錄頁面form中加入以下代碼:
<input id="captcha" type="text" name="captcha" placeholder="請輸入驗證碼"/>
<img class="security-code-img" src="kaptcha.jpg" >
package org.chengli.cas.constans;
public interface CustomConstants {
String LOGIN_FIRST = "LOGIN_FIRST";
String FIRST = "FIRST";
String NOTFIRST = "NOTFIRST";
}
(2)在CustomAuthenticationViaFormAction類中customValidator方法HttpSession session = request.getSession();下面 加入以下代碼:
Object loginObject = session.getAttribute(CustomConstants.LOGIN_FIRST);
if(loginObject == null || CustomConstants.FIRST.equals(String.valueOf(loginObject))){
session.setAttribute(CustomConstants.LOGIN_FIRST, CustomConstants.NOTFIRST);
return new Event(this, SUCCESS);
}
注:我使用的session中存儲,也就是說你輸入密碼錯誤後,需要你輸入驗證碼,但是你關閉瀏覽器後在打開還是不需要你輸入的。你也可以
<c:if test="${sessionScope.LOGIN_FIRST == 'NOTFIRST'}">
這裏放驗證碼的代碼哦
</c:if>
(4)到這裏基本上就已經實現了,如果你的有問題可以留言一起討論。效果如下: