如何在现有Java Swing程序中添加登录屏幕?

时间:2013-04-09 17:15:29

标签: java swing security user-interface

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

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

3 个答案:

答案 0 :(得分: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);
            }
        });
    }
}

答案 1 :(得分:0)

执行main方法后,您可以使用带有Swing的DialogBox。然后,根据代码,您可以验证。如果使用身份验证数据(从数据库,文件等传入)输入的值是正常的,那么您将显示主UI,如果没有,也许您可​​以显示“再试一次”或关闭对话框等对话框。

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

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

答案 2 :(得分: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;
    }
}

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