2

我已经有一个非常基本的 Java Swing 程序,但我意识到我可以使用一个简单的用户名/密码登录屏幕来限制只有拥有用户名和密码的人才能访问它。

无论如何,我可以在 main 方法的开头插入一些代码,这将阻止执行超出它,直到在出现的屏幕上输入用户名和密码?

4

3 回答 3

9

这是登录对话框的示例。关闭整个程序并关闭对话框。

用户名:stackoverflow密码:stackoverflow

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TestFrame extends JFrame {

    private PassWordDialog passDialog;

    public TestFrame() {
        passDialog = new PassWordDialog(this, true);
        passDialog.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new TestFrame();
                frame.getContentPane().setBackground(Color.BLACK);
                frame.setTitle("Logged In");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            }
        });
    }
}

class PassWordDialog extends JDialog {

    private final JLabel jlblUsername = new JLabel("Username");
    private final JLabel jlblPassword = new JLabel("Password");

    private final JTextField jtfUsername = new JTextField(15);
    private final JPasswordField jpfPassword = new JPasswordField();

    private final JButton jbtOk = new JButton("Login");
    private final JButton jbtCancel = new JButton("Cancel");

    private final JLabel jlblStatus = new JLabel(" ");

    public PassWordDialog() {
        this(null, true);
    }

    public PassWordDialog(final JFrame parent, boolean modal) {
        super(parent, modal);

        JPanel p3 = new JPanel(new GridLayout(2, 1));
        p3.add(jlblUsername);
        p3.add(jlblPassword);

        JPanel p4 = new JPanel(new GridLayout(2, 1));
        p4.add(jtfUsername);
        p4.add(jpfPassword);

        JPanel p1 = new JPanel();
        p1.add(p3);
        p1.add(p4);

        JPanel p2 = new JPanel();
        p2.add(jbtOk);
        p2.add(jbtCancel);

        JPanel p5 = new JPanel(new BorderLayout());
        p5.add(p2, BorderLayout.CENTER);
        p5.add(jlblStatus, BorderLayout.NORTH);
        jlblStatus.setForeground(Color.RED);
        jlblStatus.setHorizontalAlignment(SwingConstants.CENTER);

        setLayout(new BorderLayout());
        add(p1, BorderLayout.CENTER);
        add(p5, BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        addWindowListener(new WindowAdapter() {  
            @Override
            public void windowClosing(WindowEvent e) {  
                System.exit(0);  
            }  
        });


        jbtOk.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if ("stackoverflow".equals(String.valueOf(jpfPassword.getPassword()))
                        && "stackoverflow".equals(jtfUsername.getText())) {
                    parent.setVisible(true);
                    setVisible(false);
                } else {
                    jlblStatus.setText("Invalid username or password");
                }
            }
        });
        jbtCancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                parent.dispose();
                System.exit(0);
            }
        });
    }
}
于 2013-11-29T13:08:10.883 回答
0

这是非常棘手的事情(正如您可能意识到的那样),以确保有人无法回避您的身份验证。

如果您不太关心是否有人可以通过它,那么完成您正在尝试的一个简单方法是创建一个变量跟踪登录过程,并且不允许您的主线程启动 GUI 线程主应用程序,直到身份验证完成。像这样的东西会起作用:

public class MyApp {

    private static boolean isAuthenticated;

    public static void main( String args[] ) {
        isAuthenticated = false;
        while( !isAuthenicated ) {
            authenticateUser();
            try{ Thread.sleep( 200 ); } catch( InterruptedException ie ){ }
        }

        new JFrame();
        // finish rest of GUI code.
    }

    private static void authenticateUser(){
        dialog = new MyAuthenticationDialog();
        dialog.show();
        if( isValid( dialog.getUsername(), dialog.getPassword() )
            isAuthenticated = true;
        else 
            isAuthenticated = false;
    }
}

但是,如果您关心这是否可以被逆向工程(这个例子对我来说是微不足道的),那么您将需要一些使用正确的用户名和密码作为密钥的加密值。将这些散列到一个 SHA-256 密钥中并加密该值。请注意,RE 仍然可以绕过这一点,但需要付出更多努力,特别是如果您反复检查是否可以使用用户在代码中随机提供的凭据解密该值。不要使用单个函数,否则 RE 只需要修补一个函数,他的工作很容易。归根结底,您无法控制客户端,因此没有完美的解决方案。这些是一些想法。还要通过Java obfuscator运行您的最终代码。

于 2013-04-09T20:08:01.143 回答
-1

执行您的main方法后,您可以立即将 DialogBox 与 Swing 一起使用。然后,根据代码,您可以进行验证。如果输入的值与身份验证数据(来自数据库、文件等)一致,那么您将显示您的主 UI,如果不是,也许您可​​以显示一个带有“重试”之类的对话框或关闭对话框。

http://java.about.com/od/UsingDialogBoxes/a/How-To-Make-A-Password-Dialog-Box.htm

希望它有帮助,最好的问候。

于 2013-04-09T17:42:35.897 回答