我对 Java EE 很陌生,在开始创建我想要创建的应用程序时遇到了很多麻烦。我想要的是一个连接到 EJB 项目的 Swing 应用程序客户端。我正在使用 Glassfish v3.1.1。到目前为止,我拥有的是两个无状态 bean,其中一个是使用 @DeclareRoles 和 Glassfish 中的 JDBC 领域以及客户端的开始来保护的。
当客户端运行时,您可以选择用户名,输入密码,然后登录。如果您使用正确的密码,一切都会正常(客户端控制台会显示一些“安全”信息)。但是,如果您输入错误的密码,您将被永久锁定。 InitialContext.lookup 不会再次调用 CallbackHandler 来检查新密码,它会继续使用不正确的凭据。
有人可以告诉我如何正确执行此操作吗?对于这种情况,我是否使用了正确的方法 - 网络上有大量信息,但基本上没有我想要做的事情的示例?一切似乎只适用于 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?
应用程序客户端.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>
机械中心。登录回调处理程序:
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 应用程序客户端。
机械中心.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);
}
}
}