JsfCaptcha : 显示正确的验证码值
JsfCaptcha : show correct captcha value
我正在使用 JsfCaptcha 来尝试处理离线验证码验证。虽然有一种方法可以验证 "what the user entered matches what the captcha image has shown",但我很难实际打印出服务器声明的正确解决方案。我预计这很容易完成,但对于我来说,无法弄清楚。以下是我使用该库的方式:
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();
起初,我浏览了所有 public getter,但其中 none 公然向我提供了我需要的数据。在尝试了所有这些之后,我走上了 jdgui 路线,在那里我反编译了库并试图寻找可以给我这些数据的解决方案/方法。
可悲的是,JsfCaptcha class 在 base class 扩展的 5-6 层以下,具有大量受保护/私有方法。显然,对非常简单的东西进行非常乏味和不必要的搜索。
是否可以打印出正在验证的实际 JsfCaptcha 值?
我终于设法解决了 javassist, by modifying the generated bytecode of the Botdetect library 的问题。我这样做是因为我 无法找到任何 getter 方法来访问实际的验证码解决方案 。显然,这不是一个干净的解决方案,但它是一个解决方案,因为您只想调试代码以确定为什么您输入的代码与后端服务器的代码不匹配。现在,我会考虑将此作为一种解决方案,直到出现不需要字节码操作的更简洁的替代方案为止。以下是我玩过的版本的详细信息:
botdetect-4.0.beta3.5jar
botdetect-jsf20-4.0.beta3.5.jar
botdetect-servlet-4.0.beta3.5.jar
当执行 checkInputMatches() 方法来验证验证码时,此结构将在后端针对提到的 jars 执行:
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 ( third argument from Step 4 ) to show the actual code.
这里是用jdgui拍的照片,通过照片我得出了这样的结论:
考虑到这一点,下面是如何在使用 javassits 执行该代码时打印该值(我使用的是 javassist-3.18.1-GA.jar,在 Tomcat ) :
@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: \" + "
+ " + \"; expected-captcha: \" + + \";\" );");
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;
我正在使用 JsfCaptcha 来尝试处理离线验证码验证。虽然有一种方法可以验证 "what the user entered matches what the captcha image has shown",但我很难实际打印出服务器声明的正确解决方案。我预计这很容易完成,但对于我来说,无法弄清楚。以下是我使用该库的方式:
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();
起初,我浏览了所有 public getter,但其中 none 公然向我提供了我需要的数据。在尝试了所有这些之后,我走上了 jdgui 路线,在那里我反编译了库并试图寻找可以给我这些数据的解决方案/方法。
可悲的是,JsfCaptcha class 在 base class 扩展的 5-6 层以下,具有大量受保护/私有方法。显然,对非常简单的东西进行非常乏味和不必要的搜索。
是否可以打印出正在验证的实际 JsfCaptcha 值?
我终于设法解决了 javassist, by modifying the generated bytecode of the Botdetect library 的问题。我这样做是因为我 无法找到任何 getter 方法来访问实际的验证码解决方案 。显然,这不是一个干净的解决方案,但它是一个解决方案,因为您只想调试代码以确定为什么您输入的代码与后端服务器的代码不匹配。现在,我会考虑将此作为一种解决方案,直到出现不需要字节码操作的更简洁的替代方案为止。以下是我玩过的版本的详细信息:
botdetect-4.0.beta3.5jar
botdetect-jsf20-4.0.beta3.5.jar
botdetect-servlet-4.0.beta3.5.jar
当执行 checkInputMatches() 方法来验证验证码时,此结构将在后端针对提到的 jars 执行:
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 ( third argument from Step 4 ) to show the actual code.
这里是用jdgui拍的照片,通过照片我得出了这样的结论:
考虑到这一点,下面是如何在使用 javassits 执行该代码时打印该值(我使用的是 javassist-3.18.1-GA.jar,在 Tomcat ) :
@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: \" + "
+ " + \"; expected-captcha: \" + + \";\" );");
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;