JsfCaptcha: показать правильное значение капчи - PullRequest
0 голосов
/ 03 апреля 2019

Я использую 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, которое проверяется?

1 Ответ

0 голосов
/ 03 апреля 2019

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

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, благодаря которой я пришел к такому выводу:

enter image description here

Имея это в виду, вот как вы можете распечатать это значение, когда этот код выполняется с использованием 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);
        }

    }

}

С учетом этого ввода и задачи:

enter image description here

В ваших логах вы видите такое сообщение:

Botdetect-DEBUG: entered-captcha: U33aZ; expected-captcha: U49a6;
...