CAS自定义错误信息

网上好多都是4.0以前的教程,但好像和4.0以后的版本多少有些出入,研究以后在此记录一下。

一、首先我们需要自定义负责认证的这个类

自定义这个类才能抛出我们自定义的异常,比如说帐号已过期,帐号被禁用什么的。

deployerConfigContext.xml里原来默认的是

class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
自定义一个验证类
import java.security.GeneralSecurityException;

import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.validation.constraints.NotNull;

import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;

import com.innochina.exception.MyAccountDisabledException;

public class MyQueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {

	@NotNull
	private String sql;

	protected final HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential)
			throws GeneralSecurityException, PreventedException {
		String username = credential.getUsername();
		String encryptedPassword = getPasswordEncoder().encode(credential.getPassword());
		try {
			String dbPassword = (String) getJdbcTemplate().queryForObject(this.sql, String.class,
					new Object[] { username });
			if (!dbPassword.equals(encryptedPassword)) {
				throw new FailedLoginException("Password does not match value on record.");
			}
			
			String status = (String) getJdbcTemplate().queryForObject("select status from user_info where mobile = ?", String.class,
					new Object[] { username });
			if (!status.equals("1")) {
				throw new MyAccountDisabledException();
			}
		} catch (IncorrectResultSizeDataAccessException e) {
			if (e.getActualSize() == 0) {
				throw new AccountNotFoundException(username + " not found with SQL query");
			}
			throw new FailedLoginException("Multiple records found for " + username);
		} catch (DataAccessException e) {
			throw new PreventedException("SQL exception while executing query for " + username, e);
		}
		return createHandlerResult(credential, new SimplePrincipal(username), null);
	}

	public void setSql(String sql) {
		this.sql = sql;
	}
}

其中的 MyAccountDisabledException() 是我自定义的异常

二、自定义异常类

public class MyAccountDisabledException extends LoginException {

    private static final long serialVersionUID = 802556922354616286L;

    
    public MyAccountDisabledException() {
        super();
    }

    
    public MyAccountDisabledException(String msg) {
        super(msg);
    }
}
三、配置拦截器里配置上这个异常

这个异常现在拦截器里不认的,抛出这个异常最终显示的是messages.properties里authenticationFailure.UNKNOWN配置的错误信息。

为了能识别这个异常,我们需要修改下异常的拦截器

在cas-servlet.xml中找到

这个就是异常的拦截器了

具体方法是

public String handle(final AuthenticationException e, final MessageContext messageContext) {
        if (e != null) {
            for (final Class kind : this.errors) {
                for (final Class handlerError : e.getHandlerErrors().values()) {
                    if (handlerError != null && handlerError.equals(kind)) {
                        final String messageCode = this.messageBundlePrefix + handlerError.getSimpleName();
                        messageContext.addMessage(new MessageBuilder().error().code(messageCode).build());
                        return handlerError.getSimpleName();
                    }
                }

            }
        }
        final String messageCode = this.messageBundlePrefix + UNKNOWN;
        logger.trace("Unable to translate handler errors of the authentication exception {}. Returning {} by default...", e, messageCode);
        messageContext.addMessage(new MessageBuilder().error().code(messageCode).build());
        return UNKNOWN;
    }
可以看到他迭代的是errors这个list

再看下errors这个list里都有什么

static {
        DEFAULT_ERROR_LIST.add(javax.security.auth.login.AccountLockedException.class);
        DEFAULT_ERROR_LIST.add(javax.security.auth.login.FailedLoginException.class);
        DEFAULT_ERROR_LIST.add(javax.security.auth.login.CredentialExpiredException.class);
        DEFAULT_ERROR_LIST.add(javax.security.auth.login.AccountNotFoundException.class);
        DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.AccountDisabledException.class);
        DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.InvalidLoginLocationException.class);
        DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.InvalidLoginTimeException.class);
        DEFAULT_ERROR_LIST.add(com.innochina.exception.MyAccountDisabledException.class);
    }

    /** Ordered list of error classes that this class knows how to handle. */
    @NotNull
    private List> errors = DEFAULT_ERROR_LIST;
最后的这条DEFAULT_ERROR_LIST.add(com.innochina.exception.MyAccountDisabledException.class);就是我自定义的异常类了

迭代匹配上后设置messageCode = this.messageBundlePrefix + handlerError.getSimpleName();

最后得出的messageCode 就是authenticationFailure.MyAccountDisabledException。

四、在messages.properties中添加错误信息

在文件中添加authenticationFailure.MyAccountDisabledException=****  具体什么错误信息自己写就行

五、修改login-webflow.xml

最后一步还得修改一下login-webflow.xml中的


    
    
    
    
    
    
    
    
    
    
  
添加上最后那一条

OK,这样配置的错误信息就能在前台显示了。



哈哈






你可能感兴趣的:(CAS)