cas 4.1.5 添加验证码 亲测成功

转自 http://blog.csdn.net/attackmind/article/details/52052502 

1、在cas工程的web.xml增加验证码功能的支持:

<!-- 验证码功能 -->  
<servlet>  
    <servlet-name>Kaptcha</servlet-name>  
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>  
    <init-param>  
        <param-name>kaptcha.border</param-name>  
        <param-value>no</param-value>  
    </init-param>  
    <init-param>  
        <param-name>kaptcha.textproducer.char.space</param-name>  
        <param-value>5</param-value>  
    </init-param>  
    <init-param>  
        <param-name>kaptcha.textproducer.char.length</param-name>  
        <param-value>5</param-value>  
    </init-param>  
</servlet>  
  
<servlet-mapping>  
    <servlet-name>Kaptcha</servlet-name>  
    <url-pattern>/captcha.jpg</url-pattern>  
</servlet-mapping>  

2、新建一个类UsernamePasswordCredentialWithAuthCode,该类继承了

org.jasig.cas.authentication.UsernamePasswordCredential,添加一个验证码字段,

并且重写equals和hashCode方法,添加关于验证码比较的信息

package org.spire.cas.core.authentication;  
  
import javax.validation.constraints.NotNull;  
import javax.validation.constraints.Size;  
  
import org.apache.commons.lang3.builder.HashCodeBuilder;  
import org.jasig.cas.authentication.UsernamePasswordCredential;  
  
public class UsernamePasswordCredentialWithAuthCode extends  
        UsernamePasswordCredential {  
    /** 
     * 带验证码的登录界面 
     */  
    private static final long serialVersionUID = 1L;  
    /** 验证码*/  
    @NotNull  
    @Size(min = 1, message = "required.authcode")  
    private String authcode;  
  
    /** 
     *  
     * @return 
     */  
    public final String getAuthcode() {  
        return authcode;  
    }  
  
    /** 
     *  
     * @param authcode 
     */  
    public final void setAuthcode(String authcode) {  
        this.authcode = authcode;  
    }  
  
    @Override  
    public boolean equals(final Object o) {  
        if (this == o) {  
            return true;  
        }  
        if (o == null || getClass() != o.getClass()) {  
            return false;  
        }  
  
        final UsernamePasswordCredentialWithAuthCode that = (UsernamePasswordCredentialWithAuthCode) o;  
  
        if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                : that.getPassword() != null) {  
            return false;  
        }  
  
        if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                : that.getPassword() != null) {  
            return false;  
        }  
        if (authcode != null ? !authcode.equals(that.authcode)  
                : that.authcode != null)  
            return false;  
  
        return true;  
    }  
  
    @Override  
    public int hashCode() {  
        return new HashCodeBuilder().append(getUsername())  
                .append(getPassword()).append(authcode).toHashCode();  
    }  
  
}  

3.新建一个类AuthenticationViaFormActionWithAuthCode,该类继承了org.jasig.cas.web.flow.AuthenticationViaFormAction类,增加一个验证码方法validatorCode:

package org.spire.cas.core.authentication;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  
  
import org.apache.commons.lang3.StringUtils;  
import org.jasig.cas.authentication.Credential;  
import org.jasig.cas.authentication.RootCasException;  
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.webflow.execution.RequestContext;  
  
/** 
 * 验证码校验类 
 *  
 * @author Langyou02 
 * 
 */  
public class AuthenticationViaFormActionWithAuthCode extends  
        AuthenticationViaFormAction {  
    /** 
     * authcode check 
     */  
    public final String validatorCode(final RequestContext context,  
            final Credential credentials, final MessageContext messageContext)  
            throws Exception {  
        final HttpServletRequest request = WebUtils  
                .getHttpServletRequest(context);  
        HttpSession session = request.getSession();  
        String authcode = (String) session  
                .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
        session.removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
  
        UsernamePasswordCredentialWithAuthCode upc = (UsernamePasswordCredentialWithAuthCode) credentials;  
        String submitAuthcode = upc.getAuthcode();  
        if (StringUtils.isEmpty(submitAuthcode)  
                || StringUtils.isEmpty(authcode)) {  
            populateErrorsInstance(new NullAuthcodeAuthenticationException(),  
                    messageContext);  
            return "error";  
        }  
        if (submitAuthcode.equals(authcode)) {  
            return "success";  
        }  
        populateErrorsInstance(new BadAuthcodeAuthenticationException(),  
                messageContext);  
        return "error";  
    }  
  
    private void populateErrorsInstance(final RootCasException e,  
            final MessageContext messageContext) {  
  
        try {  
            messageContext.addMessage(new MessageBuilder().error()  
                    .code(e.getCode()).defaultText(e.getCode()).build());  
        } catch (final Exception fe) {  
            logger.error(fe.getMessage(), fe);  
        }  
    }  
}  

其中NullAuthcodeAuthenticationException和BadAuthcodeAuthenticationException是自定义的异常类,用于取得异常码:

/* 
 * Licensed to Jasig under one or more contributor license 
 * agreements. See the NOTICE file distributed with this work 
 * for additional information regarding copyright ownership. 
 * Jasig licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License.  You may obtain a 
 * copy of the License at the following location: 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied.  See the License for the 
 * specific language governing permissions and limitations 
 * under the License. 
 */  
package org.spire.cas.core.authentication;  
  
import org.jasig.cas.authentication.RootCasException;  
  
/** 
 * The exception to throw when we know the authcode is null 
 *  
 * @author Scott Battaglia 
 * @version $Revision$ $Date$ 
 * @since 3.0 
 */  
public class NullAuthcodeAuthenticationException extends RootCasException {  
      
    /** Serializable ID for unique id. */  
    private static final long serialVersionUID = 5501212207531289993L;  
  
    /** Code description. */  
    public static final String CODE = "required.authcode";  
  
    /** 
     * Constructs a TicketCreationException with the default exception code. 
     */  
    public NullAuthcodeAuthenticationException() {  
        super(CODE);  
    }  
  
    /** 
     * Constructs a TicketCreationException with the default exception code and 
     * the original exception that was thrown. 
     *  
     * @param throwable the chained exception 
     */  
    public NullAuthcodeAuthenticationException(final Throwable throwable) {  
        super(CODE, throwable);  
    }}  
  
  
/* 
 * Licensed to Jasig under one or more contributor license 
 * agreements. See the NOTICE file distributed with this work 
 * for additional information regarding copyright ownership. 
 * Jasig licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License.  You may obtain a 
 * copy of the License at the following location: 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied.  See the License for the 
 * specific language governing permissions and limitations 
 * under the License. 
 */  
package org.spire.cas.core.authentication;  
  
import org.jasig.cas.authentication.RootCasException;  
  
/** 
 * The exception to throw when we know the authcoe is not correct 
 *  
 * @author Scott Battaglia 
 * @version $Revision$ $Date$ 
 * @since 3.0 
 */  
public class BadAuthcodeAuthenticationException extends RootCasException {  
      
    /** Serializable ID for unique id. */  
    private static final long serialVersionUID = 5501212207531289993L;  
  
    /** Code description. */  
    public static final String CODE = "error.authentication.authcode.bad";  
  
    /** 
     * Constructs a TicketCreationException with the default exception code. 
     */  
    public BadAuthcodeAuthenticationException() {  
        super(CODE);  
    }  
  
    /** 
     * Constructs a TicketCreationException with the default exception code and 
     * the original exception that was thrown. 
     *  
     * @param throwable the chained exception 
     */  
    public BadAuthcodeAuthenticationException(final Throwable throwable) {  
        super(CODE, throwable);  
    }}  

4、在spire_cas工程的login_webflow.xml修改登录验证流程:

<view-state id="viewLoginForm" view="casLoginView" model="credential">  
       <binder>  
           <binding property="username" required="true"/>  
           <binding property="password" required="true"/>  
           <binding property="authcode" required="true"/>  
           <binding property="rememberMe" />  
       </binder>  
       <on-entry>  
           <set name="viewScope.commandName" value="'credential'"/>  
  
           <!-- 
           <evaluate expression="samlMetadataUIParserAction" /> 
           -->  
       </on-entry>  
       <transition on="submit" bind="true" validate="true" to="authcodeValidate">  
            
       </transition>    
   </view-state>  
<action-state id="authcodeValidate">      
       <evaluate expression="authenticationViaFormAction.validatorCode(flowRequestContext, flowScope.credential, messageContext)" />      
       <transition on="error" to="generateLoginTicket" />      
       <transition on="success" to="realSubmit" />      
   </action-state>    

并修改cas-servlet.xmlbean id ="AuthenticationViaFormAction"的class="org.spire.cas.core.authentication.AuthenticationViaFormActionWithAuthCode";

5、增加国际化显示信息:

screen.welcome.label.authcode=\u9A8C\u8BC1\u7801:

screen.welcome.label.authcode.accesskey=a

required.authcode=\u5FC5\u987B\u5F55\u5165\u9A8C\u8BC1\u7801\u3002

error.authentication.authcode.bad=\u9A8C\u8BC1\u7801\u8F93\u5165\u6709\u8BEF\u3002

6、登录页面casLoginView.jsp添加验证码输入框:

<section class="row fl-controls-left">  
        <label for="authcode"><spring:message code="screen.welcome.label.authcode" /></label>  
        <spring:message code="screen.welcome.label.authcode.accesskey" var="authcodeAccessKey" />  
        <table>  
            <tr>  
                <td>  
                    <form:input cssClass="required" cssErrorClass="error" id="authcode" size="10" tabindex="2" path="authcode"  accesskey="${authcodeAccessKey}" htmlEscape="true" autocomplete="off" />  
                </td>  
                <td style="vertical-align: bottom;">  
                    <img onclick="this.src='captcha.jpg?'+Math.random()" width="93" height="30" src="captcha.jpg">  
                                    </td>  
            </tr>  
        </table>  
       </section>  

7、如果要默认中文页面显示,修改cas-servlet.xml 下的local Resolver默认值为zh_CN:

 

 <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" p:defaultLocale="zh_CN" />

8、效果图(spire_cas是另外一个web工程登录跳转到cas服务器认证):

9、参考博文:http://blog.csdn.net/zhu_tianwei/article/details/19153549

转载于:https://my.oschina.net/u/2380830/blog/835328

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值