Проблемы с пониманием структуры вокруг примера JXLoginPane

Я нашел компонент под названием JXLoginPane из SwingX, доступный в WindowBuilder, и мне кажется, что это было бы неплохо. отправной точкой для того, что я пытаюсь сделать, но мне нужно больше информации о том, как его использовать. Пока единственное, что мне действительно помогло, это эта 9- запись в блоге летней давности.

Это действительно дает мне большую часть пути, но есть несколько ссылок на такие вещи, как is.IS_Statics, is.MD5Hash и isquote.Main, которые автор не предоставляет. Я предполагаю, что это классы, которые он или она создали только для входа в систему, но я понятия не имею, как создать их для себя.

Как мне конкретизировать то, что Ракстон начал в своем блоге? Или, если на то пошло, может ли кто-нибудь порекомендовать еще лучшую альтернативу JXLoginPane?


person Sturm    schedule 30.07.2014    source источник


Ответы (2)


Все ответы будут зависеть от ваших требований, но самое главное, вы понимаете, что такое JXLoginPane и как он работает. Тогда вы сможете понять это сообщение 9-летней давности:

  • JXLoginPane: создает панель с элементами управления для аутентификации пользователей в приложении на основе входа.

  • LoginService: абстрактный базовый класс, который должен выполнять логику входа в систему. и определить, действительна ли аутентификация пользователя или нет. Он хранит внутренний список объектов LoginListeners, которые уведомляются об LoginEvents во время весь процесс входа в систему: вход в систему начался, отменен, успешно и неудачно.

  • PasswordStore: абстрактный класс, предназначенный для безопасного хранения паролей, введенных пользователями в некоторых вид кеша, чтобы помочь LoginService аутентифицировать пользователей. Фактический механизм, используемый для хранения паролей, оставлен на усмотрение реализации.

  • UserNameStore: то же, что и PasswordStore, но для имен пользователей.

  • LoginListener: этот интерфейс предоставляет контракт для "прослушивания" текущего входа в систему. процесс и действие в результате. Например, если попытка входа в систему для одного и того же пользователя не удалась 5 раз, вы можете заблокировать этого пользователя, предполагая, что кто-то пытается взломать эту учетную запись, или, если процесс входа в систему прошел успешно, вы можете создать новую запись сеанса в своей базе данных, если вы заинтересованы в сохранении лог-таблица с сессиями пользователей.


Теперь, взглянув на этот пост, я думаю, что это реализация на основе службы базы данных в сочетании с Настройки на основе кэша имен пользователей для UserNameStore:

  • Класс is.ISLoginService — это реализация LoginService абстрактного базового класса.

  • Класс is.ISUserNameStore является реализацией абстрактного класса UserNameStore.

  • Для PasswordStore абстрактного класса нет реализации.

  • Класс is.ISLoginListener представляет собой реализацию интерфейса LoginListener.

Наконец, что касается is.IS_Statics, is.MD5Hash и isquote.Main, они кажутся служебными классами этого конкретного проекта и не имеют ничего общего с основами JXLoginPane. У вас, вероятно, будут свои собственные классы, которые помогут вам в процессе входа в систему.


Простой пример

Пожалуйста, рассмотрите этот простой пример, который иллюстрирует описанные выше концепции. Вы увидите, что не так уж и сложно заставить его работать.

Примечание. нет реализации хранилища имен пользователей и паролей.
Примечание 2. см. LoginAdapter

import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.JXLoginPane;
import org.jdesktop.swingx.auth.LoginAdapter;
import org.jdesktop.swingx.auth.LoginEvent;
import org.jdesktop.swingx.auth.LoginListener;
import org.jdesktop.swingx.auth.LoginService;

public class Demo {

    private JFrame frame;
    private String userName;
    private int failedAttemptsCount = 0;

    private void showLoginDialog() {

        frame = new JFrame("Welcome!");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JXLoginPane loginPane = new JXLoginPane();

        LoginListener loginListener = new LoginAdapter() {
            @Override
            public void loginFailed(LoginEvent source) {
                failedAttemptsCount++;
                String message;
                switch(failedAttemptsCount) {
                    case 1: message = "Come on buddy! What happened?"; break;
                    case 2: message = "Did you just fail again?"; break;
                    case 3: message = "This is embarrassing..."; break;
                        default: message = "You should probably go home and get some sleep...";
                }
                loginPane.setErrorMessage(message);
            }

            @Override
            public void loginSucceeded(LoginEvent source) {
                Demo.this.userName = loginPane.getUserName();
                Demo.this.createAndShowGui();
            }
        };

        LoginService loginService = new LoginService() {
            @Override
            public boolean authenticate(String name, char[] password, String server) throws Exception {
                return name.equals("Sturm") 
                    && String.valueOf(password).equals("StackOverflow") ;
            }
        };

        loginService.addLoginListener(loginListener);
        loginPane.setLoginService(loginService);

        JXLoginPane.JXLoginDialog dialog = new JXLoginPane.JXLoginDialog(frame, loginPane);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);

        // if loginPane was cancelled or closed then its status is CANCELLED
        // and still need to dispose main JFrame to exiting application
        if(loginPane.getStatus() == JXLoginPane.Status.CANCELLED) {
            frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
        }
    }

    private void createAndShowGui() {
        String welcomeMessage = String.format("Welcome %s ! You have successfuly loged in.", userName);
        JPanel panel = new JPanel();
        panel.add(new JLabel(welcomeMessage));

        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().showLoginDialog();
            }
        });
    }
}
person dic19    schedule 30.07.2014
comment
Да, похоже, что автор блога использовал какую-то другую утилиту, которая использует is в качестве идентификатора для создаваемых им классов. is.IS_Statics, например, скорее всего, это просто набор static вспомогательных методов. И я предполагаю, что в классе is.MD5Hash есть вещи для шифрования/соления паролей и тому подобного. Об этом я хотел бы узнать больше. Но я буду больше изучать те абстрактные классы и интерфейсы, о которых вы упомянули, в надежде лучше понять все это. Спасибо. - person Sturm; 31.07.2014
comment
Добро пожаловать. Как только вы правильно поймете этот API, вы поблагодарите команду SwingLabs. Если вам интересно узнать о шифровании/солении, то это отличная статья для начала: Хеширование паролей с солью — делаем правильно @Sturm - person dic19; 31.07.2014

Поскольку вы только начинаете, лично я бы не стал использовать JXLoginPane. Кодирование собственной панели входа не очень сложно, и я думаю, что это отличное место, чтобы узнать о кодировании графических интерфейсов и использовании Swing.

Я должен предположить, что вы знаете основы использования свинга. Если нет, вам действительно придется начать с нуля и пройти обучение по созданию и использованию основных компонентов свинга. Я бы также порекомендовал netbeans в качестве вашей IDE, конструктор графического интерфейса вполне приличный для начала.

Что касается панели входа в систему, то все, что вам нужно, это два поля JTextField и кнопка JButton. Все остальное в основном просто доп.

Один JTextField позволит пользователю ввести свое имя пользователя, а другой — пароль. Вы поместите прослушиватель действий на JButton, который при нажатии будет искать где-то, чтобы увидеть, существует ли это имя пользователя, и если да, соответствует ли пароль, а затем выполнить соответствующее действие, т. е. разблокировать остальную часть программы для использования , сообщить пользователю, что пароль неверный и т. д. и т. д.

Возможно, это хороший простой пример? http://www.novell.com/documentation/developer/samplecode/bns_ldap_sample/LoginSample/Login.java.html

Здесь есть два метода, которые вам обязательно придется кодировать самостоятельно. doSearch() и doLogin(String fullName). Если вы только учитесь, вы можете сделать что-то простое, например, просто жестко закодировать некоторые имена пользователей и пароли или прочитать текстовый файл, чтобы увидеть, есть ли совпадения, вместо того, чтобы настраивать и подключаться к базе данных. doLogin может быть таким же простым, как отключение всех ваших JComponents, а затем их включение при успешном входе в систему.

person mbw    schedule 30.07.2014
comment
На самом деле, последние несколько месяцев я занимаюсь Swing, так что я уже не новичок в этом, хотя я все еще любитель. И кстати, WindowBuilder для Eclipse — отличная альтернатива NetBeans, ИМХО. Я не сомневаюсь, что мог бы написать свой собственный диалог входа в систему, который был бы очень простым, но это означает незащищенные пароли. И хотя безопасность в моей программе не является главной заботой, я все же хотел бы узнать о лучших способах сделать это: шифровании, добавлении соли и т. д. - person Sturm; 31.07.2014