我们的Web应用程序已部署在Tomcat上,当前使用UserDatabaseRealm来确保安全。我们希望在应用程序中提供一个页面,用户可以在其中更改密码- 一种简单的通用Web应用程序功能。我找不到任何示例servlet代码来执行此操作。对UserDatabaseRealm的Tomcat描述意味着可以在服务器启动时加载XML之后以编程方式对其进行更新,并且还可以将更改保存回XML文件。简要介绍了JMX作为一种手段,但没有详细介绍。
我们的目标是在此应用程序中没有数据库,因此我们真的不想使用JDBC Realm。更改用户密码(对于管理员,添加/删除用户)的Java Servlet代码看起来像什么?
感谢您提供的线索,这是我正在工作的Tomcat MemoryUserDatabase Servlet(减去任何加密,密码验证,错误处理等):
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // Get current password for currently authenticated user String username = request.getRemoteUser(); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName userObjName = new ObjectName("Users:type=User,username=\""+username+"\",database=UserDatabase"); Object password = server.getAttribute(userObjName, "password"); System.out.println("Current Password = "+password.toString()); // Get new password from request parms and update the DB String newPw = request.getParameter("newpw"); server.setAttribute(userObjName, new Attribute("password", newPw)); // Password is updated in-memory, now write to file. // Note Tomcat MemoryUserDatabase.save() implementation does not synchronize this // operation, so it can fail badly if multiple users do this at the same time. // Ugh. Should do this in a static synchronized method. server.invoke( new ObjectName("Users:type=UserDatabase,database=UserDatabase"), "save", new Object[0], new String[0]); // If no exception, save was OK (it returns VOID, so there is no return value to check) } catch (Throwable t) { // Should return proper HTTP error code... t.printStackTrace(System.err); } }
我只是想通了。
首先,您必须更新server.xml并将readonly = false添加到:
<Resource auth="Container" readonly="false" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
然后在一个jsp文件中:
<%!public static boolean changePasswd(String user, String passwd, MBeanServer mbeanServer, JspWriter out) throws Throwable{ try { String userFDN = "Users:type=User,username=\""+user+"\",database=UserDatabase"; ObjectName userObjName = new ObjectName(userFDN); MBeanInfo info = mbeanServer.getMBeanInfo(userObjName); Attribute attr=new Attribute("password",passwd); mbeanServer.setAttribute(userObjName, attr); ObjectName databaseObjName=new ObjectName("Users:type=UserDatabase,database=UserDatabase"); Object result= mbeanServer.invoke(databaseObjName,"save",new Object[0],new String[0]); out.println("<b>Changed password and, Saved: "+result+"</b>"); return true; } catch (Throwable t) { out.print("<font color='red'>WHY: </font>" + t); } return false; }%> <%MBeanServer mbeanServer = (MBeanServer) list.get(0); //ObjectName obname = new ObjectName( "Catalina:type=Resource,resourcetype=Global,class=org.apache.catalina.UserDatabase,name=\"UserDatabase\"" ); ArrayList list = MBeanServerFactory.findMBeanServer(null); MBeanServer mbeanServer = (MBeanServer) list.get(0); changePasswd("user","passwd",mbeanServer,out);
/ N