JsfCaptcha: показывает правильное значение captcha

#jsf #captcha

#jsf #captcha

Вопрос:

Я использую JsfCaptcha в попытке обработать автономную проверку captcha. Хотя существует метод проверки того, «что введено пользователем, соответствует тому, что показано на изображении captcha», мне сложно на самом деле распечатать то, что сервер утверждает, что это правильное решение. Я ожидал, что это будет довольно легко выполнить, но, хоть убейте, не могу в этом разобраться. Вот как я использую библиотеку:

 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() демонстрирует, как библиотека проверяет, что пользователь ввел правильное решение captcha. Что я хотел бы сделать сейчас, так это в целях отладки выйти из системы, каким было решение (в случае, если пользователь ввел неправильное значение). Потенциально, что-то вроде этого:

 final String solution = captcha.getCorrectSolutionToCaptcha();
  

Сначала я просмотрел все общедоступные источники получения информации, но ни один из них не является наглым в предоставлении мне необходимых данных. Перепробовав их все, я пошел по пути jdgui, где я декомпилировал библиотеки и попытался найти решение / метод, который дал бы мне эти данные.

К сожалению, класс JsfCaptcha находится на 5-6 уровнях расширения базового класса с множеством защищенных / частных методов. Очевидно, что это очень утомительная и ненужная охота за чем-то очень простым.

Возможно ли распечатать фактическое значение JsfCaptcha, по которому выполняется проверка?

Комментарии:

1. @Kukeltje Теперь я обновил вопрос, чтобы он был как можно более подробным. Учитывая, что я ищу кодовое решение, которое не кажется очевидным на основе документации, это, вероятно, настолько подробно, насколько я могу найти решение.

Ответ №1:

Мне наконец удалось решить проблему с помощью javassist, изменив сгенерированный байт-код библиотеки Botdetect. Я сделал это, потому что мне не удалось найти какой-либо метод получения для доступа к фактическому решению captcha. Очевидно, что это не чистое решение, но это решение, учитывая, что вы просто хотите отладить свой код, чтобы определить, почему введенный вами код не соответствует коду, имеющемуся на внутреннем сервере. На данный момент я буду рассматривать это как решение, пока не появится более чистая альтернатива, не требующая манипуляций с байт-кодом. Вот подробная информация о версии, с которой я играл и заставил это работать:

 botdetect-4.0.beta3.5jar
botdetect-jsf20-4.0.beta3.5.jar
botdetect-servlet-4.0.beta3.5.jar
  

Когда метод checkInputMatches () выполняется для проверки captcha, эта структура выполняется на серверной части по отношению к упомянутым банкам:

 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 (я использую 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: "   "
                      "$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;