主要是通用改写扩展authenticationProcessingFilter类来实现,当然还有开源框架JCaptcha来生成验证码
public class AuthenticationProcessingFilter implements Filter, InitializingBean, ApplicationEventPublisherAware {
public static final String ACEGI_SAVED_REQUEST_KEY = "ACEGI_SAVED_REQUEST_KEY";
public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION";
public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String ACEGI_SECURITY_LAST_USERNAME_KEY = "ACEGI_SECURITY_LAST_USERNAME";
private ApplicationEventPublisher eventPublisher;
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private AuthenticationManager authenticationManager;
private String authenticationFailureUrl;
private String defaultTargetUrl;
private String filterProcessesUrl = getDefaultFilterProcessesUrl();
private boolean alwaysUseDefaultTargetUrl = false;
private RememberMeServices rememberMeServices = new NullRememberMeServices();
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
private Properties exceptionMappings = new Properties();
private boolean continueChainBeforeSuccessfulAuthentication = false;
public boolean isContinueChainBeforeSuccessfulAuthentication() {
return continueChainBeforeSuccessfulAuthentication;
}
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
public String getDefaultFilterProcessesUrl() {
return "/j_acegi_security_check";
}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("Can only process HttpServletRequest");
}
if (!(response instanceof HttpServletResponse)) {
throw new ServletException("Can only process HttpServletResponse");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String username = obtainUsername(httpRequest);
String password = obtainPassword(httpRequest);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
if (requiresAuthentication(httpRequest, httpResponse)) {
Authentication authResult;
try {
//加入验证码
if(!onPreAuthentication(httpRequest, httpResponse)){
httpRequest.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
username);
throw new AuthenticationCodeException("请输入正确的验证码!");
}
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
password);
setDetails(httpRequest, authRequest);
httpRequest.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,username);
authResult = this.getAuthenticationManager().authenticate(authRequest);
// Authentication success
if (continueChainBeforeSuccessfulAuthentication) {
filterChain.doFilter(httpRequest, httpResponse);
}
//可以在此加入验证成功后的功能代码
successfulAuthentication(httpRequest, httpResponse, authResult);
String targetUrl = alwaysUseDefaultTargetUrl ? null : obtainFullRequestUrl(httpRequest);
if (targetUrl == null) {
targetUrl = getDefaultTargetUrl();
}
if (!targetUrl.startsWith("http://") && !targetUrl.startsWith("https://")) {
targetUrl = httpRequest.getContextPath() + targetUrl;
}
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
return ;
} catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(httpRequest, httpResponse, failed);
String failureUrl = exceptionMappings.getProperty(failed.getClass().getName(), authenticationFailureUrl);
if (!failureUrl.startsWith("http://") && !failureUrl.startsWith("https://")) {
failureUrl = httpRequest.getContextPath() + failureUrl;
}
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(failureUrl));
return;
}
}
filterChain.doFilter(request, response);
}
public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response)
throws AuthenticationException, IOException{
String username = obtainUsername(request);
String password = obtainPassword(request);
// System.out.println("username: "+username +" passward:"+password) ;
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
password);
setDetails(request, authRequest);
request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
username);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(new WebAuthenticationDetails(request));
}
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
uri = uri.substring(0, pathParamIndex);
}
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
}
public void init(FilterConfig arg0) throws ServletException {}
public void afterPropertiesSet() throws Exception {}
public void setApplicationEventPublisher(ApplicationEventPublisher context) {
this.eventPublisher = context;
}
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public boolean isAlwaysUseDefaultTargetUrl() {
return alwaysUseDefaultTargetUrl;
}
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
}
public String getAuthenticationFailureUrl() {
return authenticationFailureUrl;
}
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
protected String obtainPassword(HttpServletRequest request) {
String password=request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);
if(password!=null){
return MD5.toMD5(request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY));
}
return password;
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
}
//加入验证码
protected boolean onPreAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
String randNum=request.getParameter("randNum");
String rand=(String)request.getSession().getAttribute("rand");
if(rand.equals(randNum)){
return true;
}
return false;
}
//可以在此加入验证成功后的功能代码
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
Authentication authResult) throws IOException {}
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException {}
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
Authentication authResult) throws IOException {
//logger.info("Authentication success: " + authResult.toString());
SecurityContextHolder.getContext().setAuthentication(authResult);
onSuccessfulAuthentication(request, response, authResult);
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
}
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException {
SecurityContextHolder.getContext().setAuthentication(null);
//logger.info("Updated SecurityContextHolder to contain null Authentication");
try {
request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
} catch (Exception ignored) {}
onUnsuccessfulAuthentication(request, response, failed);
rememberMeServices.loginFail(request, response);
}
public static String obtainFullRequestUrl(HttpServletRequest request) {
SavedRequest savedRequest = (SavedRequest) request.getSession()
.getAttribute(ACEGI_SAVED_REQUEST_KEY);
return (savedRequest == null) ? null : savedRequest.getFullRequestUrl();
}
public Properties getExceptionMappings() {
return exceptionMappings;
}
public void setExceptionMappings(Properties exceptionMappings) {
this.exceptionMappings = exceptionMappings;
}
public MessageSourceAccessor getMessages() {
return messages;
}
public void setMessages(MessageSourceAccessor messages) {
this.messages = messages;
}
public RememberMeServices getRememberMeServices() {
return rememberMeServices;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
public ApplicationEventPublisher getEventPublisher() {
return eventPublisher;
}
public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public AuthenticationDetailsSource getAuthenticationDetailsSource() {
return authenticationDetailsSource;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
}