Java EE 6应用程序客户端登录
作者:互联网
我对Java EE还是很陌生,刚开始要创建的应用程序遇到了很多麻烦.我想要的是一个连接到EJB项目的Swing应用程序客户端.我正在使用Glassfish v3.1.1.到目前为止,我有两个无状态Bean,其中一个是使用@DeclareRoles和Glassfish中的JDBC领域来保护的,另一个是客户端的开始.
运行客户端时,您可以选择用户名,键入密码,然后登录.如果使用正确的密码,则一切正常(客户端控制台会吐出某些“安全”信息).但是,如果键入错误的密码,则将您永久锁定. InitialContext.lookup不会再次调用CallbackHandler来检查新密码,而是继续使用不正确的凭据.
有人可以告诉我如何正确执行此操作吗?我是否在这种情况下使用了正确的方法-网络上有大量信息,但基本上是0种我想做的事?一切似乎只适用于J2EE或Servlet!这是一些相关的代码.
glassfish-ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
<security-role-mapping>
<role-name>Admin</role-name>
<group-name>Admin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Employee</role-name>
<group-name>Employee</group-name>
</security-role-mapping>
<enterprise-beans>
<ejb>
<ejb-name>LoginBean</ejb-name>
<jndi-name>ejb/machineryhub/LoginService</jndi-name>
</ejb>
<ejb>
<ejb-name>EmployeeBean</ejb-name>
<jndi-name>ejb/machineryhub/EmployeeService</jndi-name>
<ior-security-config>
<as-context>
<auth_method>username_password</auth_method>
<realm>machineryhub</realm>
<required>true</required>
</as-context>
</ior-security-config>
</ejb>
</enterprise-beans>
</glassfish-ejb-jar>
我是否需要添加< ior-security-config>阻止我创建的每个安全bean?
application-client.xml:
<?xml version="1.0" encoding="UTF-8"?>
<application-client version="6" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application-client_6.xsd">
<display-name>MachineryHub</display-name>
<ejb-ref>
<ejb-ref-name>LoginBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>machineryhub.service.LoginService</remote>
</ejb-ref>
<ejb-ref>
<ejb-ref-name>EmployeeBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>machineryhub.service.EmployeeService</remote>
</ejb-ref>
<callback-handler>machineryhub.LoginCallbackHandler</callback-handler>
</application-client>
Machineryhub.LoginCallbackHandler:
public class LoginCallbackHandler implements CallbackHandler {
@Override
public void handle(Callback[] clbcks) throws IOException, UnsupportedCallbackException {
LoginFrame l = LoginFrame.instance;
for (Callback cb : clbcks) {
if (cb instanceof NameCallback) {
NameCallback ncb = (NameCallback) cb;
ncb.setName(l.usernameCombo.getSelectedItem().toString());
} else if (cb instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback) cb;
pcb.setPassword(l.passwordText.getPassword());
} else {
throw new UnsupportedCallbackException(cb);
}
}
}
}
现在,很长一段时间,swing应用程序客户端.
Machineryhub.LoginFrame
public class LoginFrame extends JFrame implements ActionListener {
public static LoginFrame instance;
public static void main(String[] args) {
// Handle uncaught exceptions in the main and Swing threads
ExceptionHandler.registerExceptionHandler();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(new SubstanceMistSilverLookAndFeel());
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
(new LoginFrame()).setVisible(true);
} catch (final Exception exception) {
ExceptionHandler.handle(Thread.currentThread(), exception);
}
}
});
}
public JComboBox usernameCombo;
public JPasswordField passwordText;
private JButton loginButton;
public LoginFrame() {
// Window Setup
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Login :: MachineryHub");
this.setLocationRelativeTo(null);
this.setIconImages(IconFactory.application_images);
// Create GUI
createGui();
usernameCombo.requestFocusInWindow();
LoginFrame.instance = this;
}
private void createGui() {
// Content Pane
final JPanel contentPanel = new JPanel();
List<String> usernames = getLoginService().getUsernames();
Collections.sort(usernames);
usernameCombo = new JComboBox(usernames.toArray());
passwordText = new JPasswordField(15);
passwordText.setActionCommand("Login");
passwordText.addActionListener(this);
loginButton = new JButton("Login", IconFactory.getImageIcon(IconFactory.Icon.KEY, 16));
loginButton.setActionCommand("Login");
loginButton.addActionListener(this);
GroupLayout layout = new GroupLayout(contentPanel);
contentPanel.setLayout(layout);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(usernameCombo).addGroup(layout.createSequentialGroup().addComponent(passwordText).addComponent(loginButton)));
layout.setVerticalGroup(layout.createSequentialGroup().addComponent(usernameCombo, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE).addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(passwordText).addComponent(loginButton)));
this.setContentPane(contentPanel);
this.pack();
}
@Override
public void actionPerformed(final ActionEvent e) {
if (e == null || e.getActionCommand() == null) {
return;
}
if (e.getActionCommand().equals("Login")) {
loginButton.setEnabled(false);
passwordText.setEnabled(false);
usernameCombo.setEnabled(false);
loginButton.setIcon(IconFactory.getImageIcon(IconFactory.SpecialImage.LOADING));
try {
Context c = new InitialContext();
EmployeeService es = (EmployeeService) c.lookup("ejb/machineryhub/EmployeeService");
System.out.println("Number of employees: " + es.getAllEmployees().size());
this.dispose();
} catch (NamingException exception) {
loginButton.setEnabled(true);
passwordText.setEnabled(true);
usernameCombo.setEnabled(true);
loginButton.setIcon(IconFactory.getImageIcon(IconFactory.Icon.KEY, 16));
JOptionPane.showMessageDialog(LoginFrame.this, "Login Error: " + exception.getMessage(), "Login Error! :: MachineryHub", JOptionPane.ERROR_MESSAGE);
}
}
}
private LoginService getLoginService() {
try {
Context c = new InitialContext();
return (LoginService) c.lookup("ejb/machineryhub/LoginService");
} catch (NamingException ne) {
throw new RuntimeException(ne);
}
}
}
解决方法:
我不太肯定这是解决此问题的最佳方法,但我已经找到一种解决方法.解决方案在于使用ProgrammaticLogin类.我从application-client.xml中删除了LoginCallbackHandler类和引用.然后在登录代码中,就在创建InitialContext之前,我使用了以下非常简单的两行代码:
ProgrammaticLogin pl = new ProgrammaticLogin();
pl.login(usernameCombo.getSelectedItem().toString(), passwordText.getPassword());
不管我输入了错误的密码多少次,这似乎都有效(您也可以使用一个简单的计数器对此进行限制).我花了这么长时间才弄清楚这一点,这有点愚蠢,但是该类没有出现在Netbeans中,所以我认为这在Java EE 6中已经不再有效.但是,这只是添加Glassfish的问题/modules/security.jar到库中以使其显示.
标签:security,java-ee-6,application-client,java,java-ee 来源: https://codeday.me/bug/20191202/2087032.html