【问题标题】:How to change a user's tomcat password in servlet application?如何在 servlet 应用程序中更改用户的 tomcat 密码?
【发布时间】:2015-01-13 01:12:22
【问题描述】:

我们的 Web 应用程序部署在 Tomcat 上,目前使用 UserDatabaseRealm 来确保安全。我们希望在应用程序中提供一个页面,用户可以在其中更改密码 - 一个简单、常见的 Web 应用程序功能。我找不到任何示例 servlet 代码来执行此操作。 UserDatabaseRealm 的 Tomcat 描述暗示它可以在服务器启动时加载 XML 后以编程方式更新,它还可以将更改保存回 XML 文件。简要提到了 JMX 作为一种手段,但没有详细说明。

我们的目标是在这个应用程序中没有数据库,所以我们真的不想使用 JDBC 领域。更改用户密码(对于管理员来说,添加/删除用户)的 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);
    }
}

【问题讨论】:

  • 不要使用UserDatabaseRealm。使用支持您需要的 Realm,例如 JDBC 领域或 JNDI 领域。
  • @user3191192 不要把你的答案放在问题本身...

标签: java security tomcat servlets passwords


【解决方案1】:

我只是想通了。

首先您必须更新 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);

/否

【讨论】:

  • 它没有。这里没有任何东西可以让用户更改他的密码。
  • EJP,你看到我编辑的答案了吗? (如果是这样,请您将其标记为答案吗?也许可以更改投票?)
  • 这提供了我在 servlet 中执行此操作所需的线索,尤其是对象名称字符串......仍然必须弄清楚如何获取 MBeanServer 实例。下面发布的工作 servlet 代码。
猜你喜欢
  • 1970-01-01
  • 2020-01-25
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多