我正在使用JsfCaptcha试图处理离线验证码验证。虽然有一种方法可以验证“用户输入的内容与验证码图像显示的内容相匹配”,但我很难实际打印出服务器所说的正确解决方案。我预计这很容易完成,但对于我的生活,无法弄清楚。以下是我使用该库的方法:
import botdetect.web.jsf.JsfCaptcha;
[...]
@ManagedBean
@RequestScoped
public class MySampleBean implements Serializable {
private JsfCaptcha captcha;
private String captchaCode;
getters for above two fields
[...]
setters for above two fields
[...]
public boolean checkInputMatches() {
if (!this.captcha.validate(captchaCode)) {
return true;
}
return false;
}
}
checkInputMatches()方法演示了库如何验证用户是否已在正确的验证码解决方案中输入。我现在要做的是,出于调试目的,要注销解决方案是什么(如果用户输入了错误的值)。可能是这样的:
final String solution = captcha.getCorrectSolutionToCaptcha();
起初,我已经浏览了所有的公众获取者,但没有一个公然向我提供我需要的数据。在尝试了所有这些之后,我沿着jdgui路线走下去,在那里我反编译了这些库,并试图找到一个解决方法/方法来获取这些数据。
遗憾的是,JsfCaptcha类在基类扩展的5-6级之下,具有多种受保护/私有方法。显然,这是一件非常繁琐且不必要的事情,非常简单。
是否可以打印出正在验证的实际JsfCaptcha值?
我终于通过修改生成的javassist字节码来设法用Botdetect library来解决问题。我这样做是因为我无法找到任何访问实际验证码解决方案的getter方法。显然,这不是一个干净的解决方案,但它是一个解决方案,因为您只想调试代码以确定您输入的代码与后端服务器所具有的代码不匹配的原因。现在,我会认为这是一个解决方案,直到有一个更清洁的替代品,不需要字节码操作。以下是我玩过的版本的详细信息并使其工作:
botdetect-4.0.beta3.5jar
botdetect-jsf20-4.0.beta3.5.jar
botdetect-servlet-4.0.beta3.5.jar
当checkInputMatches()方法执行以验证验证码时,此结构将在后端针对上述jar执行:
Step 1: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.web.jsf.JsfCaptcha ->
public boolean validate(String paramString)
Step 2: ( botdetect-servlet-4.0.beta3.5.jar )
com.captcha.botdetect.web.servlet.Captcha ->
public boolean validate(String paramString)
Step 3: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.internal.core.CaptchaBase ->
public boolean validate(String paramString1, String paramString2, ValidationAttemptOrigin paramValidationAttemptOrigin, boolean paramBoolean)
Step 4: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.internal.core.captchacode.CodeCollection ->
public final boolean a(String paramString1, String paramString2, Integer paramInteger, boolean paramBoolean, ValidationAttemptOrigin paramValidationAttemptOrigin)
Step 5: Observe $3 ( third argument from Step 4 ) to show the actual code.
这是使用jdgui的照片,通过它我得出了这个结论:
考虑到这一点,以下是在使用javassits执行代码时我可以如何打印该值(我在Tomcat上使用javassist-3.18.1-GA.jar):
@ManagedBean(eager = true)
@ApplicationScoped
public class CustomBean implements Serializable {
private static final long serialVersionUID = 3121378662264771535L;
private static Logger LOG = LogManager.getLogger(CustomBean.class.getName());
@PostConstruct
public void initialize() {
try {
final ClassPool classPool = new ClassPool(ClassPool.getDefault());
classPool.insertClassPath(new ClassClassPath(this.getClass()));
classPool.insertClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
final CtClass codeCollectionClass = classPool
.get("com.captcha.botdetect.internal.core.captchacode.CodeCollection");
if (!codeCollectionClass.isFrozen()) {
final CtMethod aMethod = codeCollectionClass.getDeclaredMethod("a",
new CtClass[] { classPool.get("java.lang.String"), classPool.get("java.lang.String"),
classPool.get("java.lang.Integer"), classPool.get("boolean"),
classPool.get("com.captcha.botdetect.internal.core."
+ "captchacode.validation.ValidationAttemptOrigin") });
aMethod.insertAfter("System.out.println(\"Botdetect-DEBUG: entered-captcha: \" + "
+ "$1 + \"; expected-captcha: \" + $3 + \";\" );");
codeCollectionClass.toClass();
} else {
LOG.error("Frozen class : Unable to re-compile BotDetect for debugging.");
}
} catch (final Exception e) {
LOG.error("unable to modify the bot detect java code", e);
}
}
}
鉴于此输入和挑战:
您在日志中收到这样的消息:
Botdetect-DEBUG: entered-captcha: U33aZ; expected-captcha: U49a6;