CAS单点登录自定义登录页面错误提示

在工作项目中使用到了单点登录,采用CAS方案,发现输入错误用户名、密码或验证码登录时没有错误提示,经过反复查询资料和尝试,找到了解决方法。

版本介绍

使用的cas版本为:
客户端:cas-client-3.2.1-release
服务器端:cas-server-3.4.10-release


具体实现

使用默认的登录页面,即cas server中的/WEB-INF/view/jsp/default/ui/casLoginView.jsp,关键代码如下:

"contextPath" value="${pageContext.request.contextPath}">
"post" id="fm1" class="fm-v clearfix" 
    action='${contextPath}/login' commandName="${commandName}">
    "*" id="msg"  element="div" cssStyle="color:red"/>
    ……

首先自定义了MyCredentials,用于获取页面中提交的表单数据,如下:

package ******;

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

public class MyCredentials implements Credentials {
    private static final long serialVersionUID = 1L;
    private String username;
    private String password;
    private String uuid;
    private String code;

   省略get、set方法……

然后自定义了登录验证类,如下:

public class MyAuthenticationHandler implements AuthenticationHandler {
    protected final Log logger = LogFactory.getLog(getClass());
    private DataSource myDataSource;//使用的数据库
    public boolean authenticate(Credentials credentials)
            throws AuthenticationException {
        MyCredentials myCredentials = (MyCredentials) credentials;
        String username = myCredentials.getUsername();
        String password = myCredentials.getPassword();

        String code = myCredentials.getCode();
        String uuid = myCredentials.getUuid();

        String codeValidateResult = validateImgCode(uuid, code);
            // 验证码有问题返回页面提示。
            //注意:直接抛出异常,不要用try-catch捕获
            if ("301".equals(codeValidateResult)) {
                // 返回登录页面信息
                // "iconCodeMsg", "验证码错误"
                throw new CheckCodeErrorException();
            } else if ("302".equals(codeValidateResult)) {
                // 返回登录页面信息
                // "iconCodeMsg", "验证码已过期"
                throw new CheckCodeOutofDateException();
            } else if ("000".equals(codeValidateResult)) {
                // 去数据库中根据账号查出对应的密码,比对是否相等
                JSONObject jObject = null;
                try {
                    jObject = new MyHttpClient().loginAuthenticate(
                            username, password);
                } catch (Exception e) {
                    logger.error("验证用户名、密码时出现异常:"+e.toString());
                }
                if (jObject != null) {
                    return true;
                } else {
                    // "用户名或密码错误";
                    throw new UsernamePasswordErrorException();
                }
            } else {
                // 如果返回的是Null,则在页面上提示"系统繁忙,请稍后再试"
                throw new SystemBusyErrorException();
            }
    }

    public String validateImgCode(String uuid, String code) {
        ResourceBundle res = ResourceBundle.getBundle("messages_zh_CN");
        String checkcodeUrl = res.getString("checkcodevalidate.url");
        String url = checkcodeUrl;
        String params = "uuid=" + uuid + "&validateCode=" + code;
        try {
            String returnMsg = MyUtilMethods.requestHttpUrlPost(url, params);
            JSONObject jb = JSONObject.fromObject(returnMsg);
            return jb.getString("code");
        } catch (Exception e) {
            return null;
        }
    }

    public boolean supports(Credentials credentials) {
        // return false;
        return true;
    }

    public DataSource getMyDataSource() {
        return myDataSource;
    }

    public void setMyDataSource(DataSource myDataSource) {
        this.myDataSource = myDataSource;
    }

同时,需要修改/WEB-INF/deployerConfigContext.xml中的配置

  
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    <bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
        <property name="credentialsToPrincipalResolvers">
            <list>
                
                <bean class="org.jasig.cas.myAuthentication.MyCredentialsToPrincipalResolver">
                    <property name="myDataSource" ref="myDataSource">property>
                bean>
                <bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
            list>
        property>

        <property name="authenticationHandlers">
            <list>
                <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
                    p:httpClient-ref="httpClient" />
                
                <bean class="org.jasig.cas.myAuthentication.MyAuthenticationHandler">
                    <property name="myDataSource" ref="myDataSource"/>
                bean> 
            list>
        property>
    bean>

    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName"><value>com.mysql.jdbc.Drivervalue>property>
       <property name="url"><value>******value>property>
       <property name="username"><value>******value>property>
       <property name="password"><value>******value>property>
    bean>

    <sec:user-service id="userDetailsService">
        <sec:user name="battags" password="notused" authorities="ROLE_ADMIN" />
    sec:user-service>

    <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">bean>

    <bean id="attributeRepository"
        class="org.jasig.services.persondir.support.StubPersonAttributeDao">
        <property name="backingMap">
            <map>
                <entry key="uid" value="uid" />
                <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> 
                <entry key="groupMembership" value="groupMembership" />
            map>
        property>
    bean>
beans>

在/src/messages_zh_CN.properties中配置错误提示消息如下:

checkcode.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
checkcode.outofdate.error=\u9A8C\u8BC1\u7801\u5DF2\u8FC7\u671F
usernamepassword.error=\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF
system.busy.error=\u7CFB\u7EDF\u7E41\u5FD9\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5

最后,需要自定义异常,在异常中规定了提示的信息:

package ******;

import org.jasig.cas.authentication.handler.AuthenticationException;
public class CheckCodeErrorException extends
        AuthenticationException {

    private static final long serialVersionUID = 1L;


     public static final CheckCodeErrorException ERROR = new CheckCodeErrorException();

     /** The code description of this exception. */
     private static final String CODE= "checkcode.error";

     public CheckCodeErrorException(){
         super(CODE);
     }

     public CheckCodeErrorException(final Throwable throwable) {
         super(CODE,throwable);
     }

     public CheckCodeErrorException(final String code) {
         super(code);
     }

     public CheckCodeErrorException(final String code,
         final Throwable throwable){
         super(code,throwable);
     }
}


其它异常类似,只需要将 String CODE= “checkcode.error”换为在.properties中设置的相应的属性名即可。

参考文献:
http://blog.csdn.net/tch918/article/details/22075695?utm_source=tuicool&utm_medium=referral

你可能感兴趣的:(CAS单点登录)