3.4.11
配置Jdbc访问
配置验证码
参考连接
效果如下
创建验证码访问controller
- 验证码生成工具类,见代码1
public class AuthCode {
public static final int AUTHCODE_LENGTH = 4; // 验证码长度
public static final int SINGLECODE_WIDTH = 15; // 单个验证码宽度
public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度
public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔
public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP);
public static final int IMG_HEIGHT = SINGLECODE_HEIGHT;
public static String getAuthCode() {
String authCode = "";
for (int i = 0; i < AUTHCODE_LENGTH; i++) {
authCode += (new Random()).nextInt(10);
}
return authCode;
}
public static BufferedImage getAuthImg(String authCode) {
// 设置图片的高、宽、类型
// RGB编码:red、green、blue
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_BGR);
// 得到图片上的一个画笔
Graphics g = img.getGraphics();
// 设置画笔的颜色,用来做背景色
//#5cbdaa
//g.setColor(Color.YELLOW);
g.setColor(Color.decode("#5cbdaa"));
// 用画笔来填充一个矩形,矩形的左上角坐标,宽,高
g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
// 将画笔颜色设置为黑色,用来写字
g.setColor(Color.BLACK);
// 设置字体:宋体、不带格式的、字号
g.setFont(new Font("宋体", Font.BOLD, SINGLECODE_HEIGHT + 5));
// 输出数字
char c;
for (int i = 0; i < authCode.toCharArray().length; i++) {
// 取到对应位置的字符
c = authCode.charAt(i);
// 画出一个字符串:要画的内容,开始的位置,高度
g.drawString(c + "", i * (SINGLECODE_WIDTH + SINGLECODE_GAP) + SINGLECODE_GAP / 2, IMG_HEIGHT);
}
Random random = new Random();
// 干扰素
for (int i = 0; i < 20; i++) {
int x = random.nextInt(IMG_WIDTH);
int y = random.nextInt(IMG_HEIGHT);
int x2 = random.nextInt(IMG_WIDTH);
int y2 = random.nextInt(IMG_HEIGHT);
g.drawLine(x, y, x + x2, y + y2);
}
return img;
}
}
- controller
public class getAuthCodeController implements Controller, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
}
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String authCode = AuthCode.getAuthCode();
request.getSession().setAttribute("vcode", authCode); // 将验证码保存到session中,便于以后验证
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
try {
// 将图像输出到Servlet输出流中。
ImageIO.write(AuthCode.getAuthImg(authCode), "JPEG", response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
配置cas-server.xml
配置
<bean id="handlerMappingC" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
加入
<prop key="/authcode">authCodeController</prop>
新增一个bean
<bean id="authCodeController" class="com.xxx.authcode.getAuthCodeController" />
- 配置web.xml
在web.xml的403.hml
下加入路径,大概在130行
- 配置web.xml
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/403.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/authcode</url-pattern>
</servlet-mapping>
添加验证码验证功能
- 修改页面
- 接收表单的java bean加上vcode属性
CAS接收和验证登录表单的java bean是UsernamePasswordCredentials,这里我是增加了一个自己的UsernamePasswordVCodeCredentials的类,当然这里要继承UsernamePasswordCredentials类;
public class UsernamePasswordVCodeCredentials extends UsernamePasswordCredentials {
private static final long serialVersionUID = 1L;
@NotNull
@Size(min=1,message = "required.vcode")/*这里需要到相应的属性文件里面增加描述*/
private String vcode;
public String getVcode() {
return vcode;
}
public void setVcode(String vcode) {
this.vcode = vcode;
}
}
- 更改login-webflow.xml配置
将<var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />
改为<var name="credentials" class="com.xxx.UsernamePasswordVCodeCredentials" />
- 增加对vcode的校验方法
增加一个类,就叫MyAuthenticationViaFormAction
public class MyAuthenticationViaFormAction extends AuthenticationViaFormAction {
private final String ERROR = "error";
private final String SUCCESS = "success";
public final String validatorCode(final RequestContext context, final Credentials credentials, final MessageContext messageContext) throws Exception {
String vcode = (String) WebUtils.getHttpServletRequest(context).getSession().getAttribute("vcode");
UsernamePasswordVCodeCredentials upv = (UsernamePasswordVCodeCredentials) credentials;
if (StringUtils.isBlank(upv.getVcode()) || StringUtils.isBlank(vcode))
return ERROR;
if (upv.getVcode().toLowerCase().equals(vcode.toLowerCase())) {
return SUCCESS;
}
MessageBuilder msgBuilder = new MessageBuilder();
msgBuilder.defaultText("验证码有误!");
messageContext.addMessage(msgBuilder.error().build());
return ERROR;
}
}
修改cas-servlet.xml
将<bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"
p:centralAuthenticationService-ref="centralAuthenticationService"
p:warnCookieGenerator-ref="warnCookieGenerator"/>改成
<bean id="authenticationViaFormAction" class="com.xxx.MyAuthenticationViaFormAction" p:centralAuthenticationService-ref="centralAuthenticationService" p:warnCookieGenerator-ref="warnCookieGenerator" />
- 修改login-webflow.xml
找到id=”viewLoginForm”这个位置,将这个view-state换成;
<view-state id="viewLoginForm" view="casLoginView" model="credentials">
<binder>
<binding property="username" />
<binding property="password" />
<binding property="vcode" />
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credentials'" />
</on-entry>
<!-- 验证码添加 -->
<!--
<transition on="submit" bind="true" validate="true" to="realSubmit">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
</transition>
-->
<transition on="submit" bind="true" validate="true" to="validatorCode">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
</transition>
<!-- 验证码结束 -->
</view-state>
在下面加入:
<!-- 验证码开始 -->
<action-state id="validatorCode">
<evaluate expression="authenticationViaFormAction.validatorCode(flowRequestContext, flowScope.credentials, messageContext)" />
<transition on="error" to="generateLoginTicket" />
<transition on="success" to="realSubmit" />
</action-state>
到此,验证码功能添加完成