cas server的版本为cas-server-3.4.12-release
cas-servlet.xml 中
在bean handlerMappingC添加属性
<prop key="/captcha.htm">captchaImageCreateController</prop>
在文件中添加
<bean id="captchaImageCreateController" class="com.cc.flow.CaptchaImageCreateController"></bean>
替换
public class CustomAuthenticationViaFormAction{ private String captchaValidationParameter = "_captcha_parameter"; private String code = "code"; /** * Binder that allows additional binding of form object beyond Spring * defaults. */ private CredentialsBinder credentialsBinder; /** Core we delegate to for handling all ticket related tasks. */ @NotNull private CentralAuthenticationService centralAuthenticationService; @NotNull private CookieGenerator warnCookieGenerator; protected Logger logger = LoggerFactory.getLogger(getClass()); public final void doBind(final RequestContext context, final Credentials credentials) throws Exception { final HttpServletRequest request = WebUtils.getHttpServletRequest(context); if (this.credentialsBinder != null && this.credentialsBinder.supports(credentials.getClass())) { this.credentialsBinder.bind(request, credentials); } } public final String submit(final RequestContext context, Credentials credentials, final MessageContext messageContext) throws Exception { final HttpServletRequest request = WebUtils .getHttpServletRequest(context); if(credentials instanceof CustomLoginCredentials){ CustomLoginCredentials rmupc = (CustomLoginCredentials)credentials; String ip = getIpAddr(request); String sessionCode = (String)WebUtils.getHttpServletRequest(context).getSession().getAttribute(code); if(rmupc.getCode() == null){ final String code = "login.code.tip"; messageContext.addMessage( new MessageBuilder().error().code(code).arg("").defaultText(code).build()); return "error"; } if (!rmupc.getCode().toUpperCase().equals(sessionCode.toUpperCase())) { final String code = "login.code.error"; messageContext.addMessage( new MessageBuilder().error().code(code).arg("").defaultText(code).build()); return "error"; } Mapmessage_zh_CN.proeprties 中添加param = new HashMap (); param.put("ip", ip); rmupc.setParam(param); } // Validate login ticket final String authoritativeLoginTicket = WebUtils.getLoginTicketFromFlowScope(context); final String providedLoginTicket = WebUtils.getLoginTicketFromRequest(context); if (!authoritativeLoginTicket.equals(providedLoginTicket)) { this.logger.warn("Invalid login ticket " + providedLoginTicket); final String code = "INVALID_TICKET"; messageContext.addMessage( new MessageBuilder().error().code(code).arg(providedLoginTicket).defaultText(code).build()); return "error"; } final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context); final Service service = WebUtils.getService(context); if (StringUtils.hasText(context.getRequestParameters().get("renew")) && ticketGrantingTicketId != null && service != null) { try { final String serviceTicketId = this.centralAuthenticationService.grantServiceTicket(ticketGrantingTicketId, service, credentials); WebUtils.putServiceTicketInRequestScope(context, serviceTicketId); putWarnCookieIfRequestParameterPresent(context); return "warn"; } catch (final TicketException e) { if (e.getCause() != null && AuthenticationException.class.isAssignableFrom(e.getCause().getClass())) { populateErrorsInstance(e, messageContext); return "error"; } this.centralAuthenticationService.destroyTicketGrantingTicket(ticketGrantingTicketId); if (logger.isDebugEnabled()) { logger.debug("Attempted to generate a ServiceTicket using renew=true with different credentials", e); } } } try { WebUtils.putTicketGrantingTicketInRequestScope(context, this.centralAuthenticationService.createTicketGrantingTicket(credentials)); putWarnCookieIfRequestParameterPresent(context); return "success"; } catch (final TicketException e) { populateErrorsInstance(e, messageContext); return "error"; } } private void populateErrorsInstance(final TicketException 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); } } private void putWarnCookieIfRequestParameterPresent(final RequestContext context) { final HttpServletResponse response = WebUtils.getHttpServletResponse(context); if (StringUtils.hasText(context.getExternalContext().getRequestParameterMap().get("warn"))) { this.warnCookieGenerator.addCookie(response, "true"); } else { this.warnCookieGenerator.removeCookie(response); } } public final void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService) { this.centralAuthenticationService = centralAuthenticationService; } /** * Set a CredentialsBinder for additional binding of the HttpServletRequest * to the Credentials instance, beyond our default binding of the * Credentials as a Form Object in Spring WebMVC parlance. By the time we * invoke this CredentialsBinder, we have already engaged in default binding * such that for each HttpServletRequest parameter, if there was a JavaBean * property of the Credentials implementation of the same name, we have set * that property to be the value of the corresponding request parameter. * This CredentialsBinder plugin point exists to allow consideration of * things other than HttpServletRequest parameters in populating the * Credentials (or more sophisticated consideration of the * HttpServletRequest parameters). * * @param credentialsBinder the credentials binder to set. */ public final void setCredentialsBinder(final CredentialsBinder credentialsBinder) { this.credentialsBinder = credentialsBinder; } public final void setWarnCookieGenerator(final CookieGenerator warnCookieGenerator) { this.warnCookieGenerator = warnCookieGenerator; } /** * 获取IP地址 * @param request * @return */ public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
login.code.tip=\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801
login.code.error=\u9A8C\u8BC1\u7801\u8F93\u5165\u6709\u8BEF login.ip.error=\u60A8\u7535\u8111\u7684ip\u4E0D\u5141\u8BB8\u767B\u5F55
package com.cc.flow;import java.io.IOException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.InitializingBean;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEGImageEncoder;import com.wokejia.flow.ValidatorCodeUtil.ValidatorCode;public class CaptchaImageCreateController implements Controller, InitializingBean { @Override public void afterPropertiesSet() throws Exception { } @Override public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse response) throws Exception { ValidatorCode codeUtil = ValidatorCodeUtil.getCode(); arg0.getSession().setAttribute("code", codeUtil.getCode()); // 禁止图像缓存。 response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream sos = null; try { // 将图像输出到Servlet输出流中。 sos = response.getOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos); encoder.encode(codeUtil.getImage()); sos.flush(); sos.close(); } catch (Exception e) { } finally { if (null != sos) { try { sos.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }}
package com.cc.flow;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.util.Random;/** ** 验证码生成工具 *
* * @ClassName: ValidatorCodeUtil * @version V1.0 @date 2012-4-9 下午06:59:25 * @author 罗伟俊 * */public class ValidatorCodeUtil {public static ValidatorCode getCode(){// 验证码图片的宽度。int width = 80;// 验证码图片的高度。int height = 30;BufferedImage buffImg = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g = buffImg.createGraphics();// 创建一个随机数生成器类。Random random = new Random();// 设定图像背景色(因为是做背景,所以偏淡)g.setColor(Color.WHITE);g.fillRect(0, 0, width, height);// 创建字体,字体的大小应该根据图片的高度来定。Font font = new Font("微软雅黑", Font.HANGING_BASELINE, 28);// 设置字体。g.setFont(font);// 画边框。g.setColor(Color.BLACK);g.drawRect(0, 0, width - 1, height - 1);// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到。// g.setColor(Color.GRAY);// g.setColor(getRandColor(160, 200));// for (int i = 0; i < 155; i++) {// int x = random.nextInt(width);// int y = random.nextInt(height);// int xl = random.nextInt(12);// int yl = random.nextInt(12);// g.drawLine(x, y, x + xl, y + yl);// }// randomCode用于保存随机产生的验证码,以便用户登录后进行验证。StringBuffer randomCode = new StringBuffer();// 设置默认生成4个验证码int length = 4;// 设置备选验证码:包括"a-z"和数字"0-9"String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";int size = base.length();// 随机产生4位数字的验证码。for (int i = 0; i < length; i++) {// 得到随机产生的验证码数字。int start = random.nextInt(size);String strRand = base.substring(start, start + 1);// 用随机产生的颜色将验证码绘制到图像中。// 生成随机颜色(因为是做前景,所以偏深)// g.setColor(getRandColor(1, 100));// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));g.drawString(strRand, 15 * i + 6, 24);// 将产生的四个随机数组合在一起。randomCode.append(strRand);}// 图象生效g.dispose();ValidatorCode code = new ValidatorCode();code.image = buffImg;code.code = randomCode.toString();return code;}// 给定范围获得随机颜色static Color getRandColor(int fc, int bc) {Random random = new Random();if (fc > 255)fc = 255;if (bc > 255)bc = 255;int r = fc + random.nextInt(bc - fc);int g = fc + random.nextInt(bc - fc);int b = fc + random.nextInt(bc - fc);return new Color(r, g, b);}/*** *验证码图片封装
** @ClassName: ValidatorCode * @version V1.0 @date 2012-4-9 下午07:24:14 * @author 罗伟俊 **/public static class ValidatorCode{private BufferedImage image;private String code;/***图片流
* @return */public BufferedImage getImage() {return image;}/***验证码
* @return */public String getCode() {return code;}}}
login-webflow.xml 中替换
<var name="credentials" class="com.cc.flow.CustomLoginCredentials" />
public class CustomLoginCredentials extends RememberMeUsernamePasswordCredentials { private static final long serialVersionUID = 1L; private Mapparam; /** The username. */ @NotNull @Size(min=1,message = "required.code") private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Map getParam() { return param; } public void setParam(Map param) { this.param = param; }}
casLoginView.jsp中添加验证码
换一个