京山游侠

专注技术,拒绝扯淡
posts - 50, comments - 868, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

在SpringSide 3 中使用JCaptcha

Posted on 2009-08-24 17:45 京山游侠 阅读(6996) 评论(5)  编辑  收藏 所属分类: SpringSide开发实战
在目前的网络上,想必大家对验证图片已经司空见惯了。验证图片是区分人和计算机的一种既有效又简单的方法。为了提高网站的安全性,防止黑客利用计算机进行暴力破解和防止黑客使用程序自动提交大量垃圾信息,在我们的网站中引入验证码机制是必要的。

在SpringSide 3的Showcase中,江南白衣演示了JCaptcha。Captcha是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称,而JCaptcha是一个在该理论下的基于Java的一个实现。我终于开始看Showcase中的一些特性了,下面来谈谈把JCaptcha集成到项目中的一些想法。

首先要把如下四个jar包拷贝到项目中:
jcaptcha-1.0.jar
jcaptcha-api-1.0.jar
imaging-01012005.jar
springside3-jee-3.1.5.jar
以上四个jar文件前两个不用我多解释,imaging-01012005.jar是必须要的,因为它提供了JCaptcha需要的WaterFilter类,而springside3-jee-3.1.5.jar里面包含的就是SpringSide 3对JCaptcha的扩展。SpringSide 3对JCaptcha做了哪些扩展呢?主要表现在两个方面:一是编写了一个Filter,用来配合SpringSecurity,二是实现了一个图片生成引擎,即GMailEngine。

事实上,JCaptcha是可以直接使用的,即直接使用CaptchaService类来生成和验证图片中的信息,而CaptchaService可以使用Spring管理;但是一旦和SpringSecurity配合起来使用就比较麻烦了,因为我们不可能去修改SpringSecurity的代码,所以就只能在web.xml中配置Filter了。但是在不和SpringSecurity配合的情况下,我们还是少不了直接使用CaptchaService类,因为Filter是定制死了的,不灵活,如果我们要返回供AJAX使用的字符串,就必须得自己写代码。

好了,下面看看具体步骤。

1、先在Spring的配置文件中配置CaptchaService的Bean,如下:
<!--JCaptcha验证码服务 -->
    
<bean id="captchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService">
        
<property name="captchaEngine">
            
<bean class="org.springside.modules.security.jcaptcha.GMailEngine" />
        
</property>
        
<property name="minGuarantedStorageDelayInSeconds" value="600" />
    
</bean>

2、在web.xml中配置Filter,如下:
<!-- SpringSide's JCaptcha filter -->
    
<filter>
        
<filter-name>jcaptchaFilter</filter-name>
        
<filter-class>org.springside.modules.security.jcaptcha.JCaptchaFilter</filter-class>
        
<init-param>
            
<param-name>failureUrl</param-name>
            
<param-value>/login.action?error=2</param-value>
        
</init-param>
    
</filter>

<!-- jcaptcha图片生成URL. -->
    
<filter-mapping>
        
<filter-name>jcaptchaFilter</filter-name>
        
<url-pattern>/security/jcaptcha.jpg</url-pattern>
    
</filter-mapping>

    
<!-- jcaptcha登录表单处理URL.
                 必须放在springSecurityFilter的filter-mapping定义之前 
-->
    
<filter-mapping>
        
<filter-name>jcaptchaFilter</filter-name>
        
<url-pattern>/j_spring_security_check</url-pattern>
    
</filter-mapping>

3、在所有需要显示验证图片的JSP文件中使用如下代码:
<img id="captchaImage" src="${ctx}/security/jcaptcha.jpg" width="100" height="40" align="middle" onclick="onImageClick(this);">(如看不清,可点击图片更换)
这里的onclick函数主要是为了实现点击图片更换的效果,其代码如下:
function onImageClick(o){
    o.src 
= "/PureText/security/jcapthcha.jpg?update=" + Math.random();
}

这时候,符合SpringSecurity要求的登录界面就会自动验证用户的输入了。

但是,我们并不是只有登录这一个地方需要使用验证图片,在用户注册、发表文章等这些地方都需要用到,而且为了不让用户离开输入界面,一般使用AJAX,这时候怎么办呢?不使用Filter,我们依然可以手动验证,如下代码片断,则是在Action类中截取的:
// 验证cpatchaImage
        boolean flag = false;
        
try {
            HttpServletRequest request 
= Struts2Utils.getRequest();
            String captchaID 
= request.getSession().getId();
            String captchaValue 
= request.getParameter("captchaValue");
            ApplicationContext context 
= WebApplicationContextUtils
                    .getWebApplicationContext(Struts2Utils.getSession()
                            .getServletContext());
            CaptchaService captchaService 
= (CaptchaService) context
                    .getBean(
"captchaService");
            flag 
= captchaService
                    .validateResponseForID(captchaID, captchaValue);
        } 
catch (Exception e) {
            flag 
= false;
        }
        
if (!flag) {
            success 
= false;
            result 
+= "captcha_err.innerHTML='验证码输入错误。';";
        } 
else {
            result 
+= "captcha_err.innerHTML='';";
        }
        
if (success == false) {
            result 
+= "failed();";
            Struts2Utils.renderHtml(result, 
"encoding:UTF-8");

就这么简单。祝大家愉快!

评论

# re: 在SpringSide 3 中使用JCaptcha  回复  更多评论   

2009-08-27 14:54 by crabboy
没写完吧。
用ajax前台怎么写?

# re: 在SpringSide 3 中使用JCaptcha  回复  更多评论   

2009-08-27 19:16 by 海边沫沫
@crabboy
前台的AJAX当然是各有各的搞法啦,每一个程序员使用的方法都不一定一样,每一个框架使用的方法都不一定一样啊。

重要的是能够把数据传递给AJAX前台,至于数据采取什么样的组织方式也没有一定之规。

# re: 在SpringSide 3 中使用JCaptcha[未登录]  回复  更多评论   

2009-09-21 19:21 by 笨笨
与楼主心有灵犀,谢谢分享。

# re: 在SpringSide 3 中使用JCaptcha  回复  更多评论   

2009-11-30 20:57 by flyliying
沫沫,你太能折腾了,厉害

# re: 在SpringSide 3 中使用JCaptcha  回复  更多评论   

2012-03-23 16:40 by d
沫沫您好,请问springside是怎样和JAX-WS集成使用的?能否指点一二?

非常感谢!

只有注册用户登录后才能发表评论。


网站导航: