我想在验证用户启动服务器应用程序的授权后,启动一个用java编写的服务器应用程序。所以,我尝试使用System.console()
实现它。问题是我的服务器应用程序是使用nohup
启动的。因此,System.console()
始终返回null ...
如何在以nohup启动的JVM中使用基于控制台的用户名和密码输入。
答案 0 :(得分:6)
当你nohup java
时,你强迫JVM 而不是使用控制台。当您使用java Console
对象时,您尝试连接不存在的控制台,因此将始终获得null Console
引用。
即。它无法完成:这是一个矛盾。
来自 nohup 手册页:
如果标准输入是终端,则从/ dev / null重定向。如果标准输出是终端,则在可能的情况下将输出附加到'nohup.out',否则为'$ HOME / nohup.out'。如果标准错误是终端,则将其重定向到标准输出。要将输出保存到FILE,请使用'nohup COMMAND> FILE”。
即。它将进程与交互式I / O(基于unix / linux字符的控制台设备)断开连接,并连接到文件系统I / O.
来自Java 7 javadoc 控制台:
访问与当前Java虚拟机关联的基于字符的控制台设备(如果有)的方法。
虚拟机是否具有控制台取决于底层平台以及虚拟机的调用方式。如果从交互式命令行启动虚拟机而不重定向标准输入和输出流,则其控制台将存在,并且通常将连接到启动虚拟机的键盘和显示器。如果虚拟机是自动启动的,例如后台作业调度程序,那么它通常没有控制台。
如果此虚拟机具有控制台,则它由此类的唯一实例表示,可以通过调用System.console()方法获取该实例。如果没有可用的控制台设备,则调用该方法将返回null。
替代解决方案(减少偏好顺序):
不要使用nohup;将服务器作为Unix / Linux守护程序服务运行
守护程序服务只能通过管理员(交互式)或管理配置(自动)启动/停止。然后您不需要以“java服务器管理员”身份登录,而是使用安全的Unix / Linux登录。我希望任何连接到服务器的客户端都需要执行应用层认证(可能/可能独立于unix用户帐户)。
请参阅Tool for creating a Java daemon service on Linux和
http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
或您可靠的Unix / Linux管理员的教科书
不要使用java控制台;使用java UI屏幕提示
使用以下方法之一提示输入用户名/密码:Swing / AWT / JavaFx 使用char []存储密码(请参阅http://javarevisited.blogspot.com.au/2012/03/why-character-array-is-better-than.html和http://java.about.com/od/UsingDialogBoxes/a/How-To-Make-A-Password-Dialog-Box.htm以及http://www.devshed.com/c/a/Java/Javas-Basic-User-Interface-Components/8/)
在Gnu Screen会话
中运行没有nohup的命令Gnu屏幕继续运行程序,即使用户关闭终端窗口。服务器屏幕会话仍然处于分离模式。
(有缺陷)将用户名/密码设置为命令行参数&系统属性-DXXX :
按如下方式运行启动脚本:
<startupscriptname>.sh username password
内部<startupscriptname>.sh
:
#! /bin/sh
nohup java MainClassName -Dadmin.username=$1 -Dadmin.password=$2 > myout.txt 2>&1 &
在java中:
String adminUsername = System.getProperty("admin.username");
// Avoid String for password, so it can't be snooped in the String values pool
char[] adminPassword = System.getProperty("admin.password").toCharArray();
问题:尝试避免使用 String
作为密码。但System.getProperty
在转换为String
之前将其作为char[]
返回。
此外,当提示用户输入密码时,具有更强的安全性,而不是将密码输入作为脚本命令行参数。
(Hacky)在没有nohup的情况下运行服务器,但是然后手动“背景nohup”它
将服务器运行为:
java MainClassName
然后通过Console
输入用户名和密码。
然后运行以下之一:
nohup -p <PID>
或
disown -h <JOB>
问题:如果想在中间使用交互式用户名/密码,则无法完全编写脚本。因此,存在风险用户可能忘记执行所有步骤,这意味着应用程序在用户注销时死亡(HUP信号)。此外,disown
:stdin, stdout & stderr
的问题将无效,不会被重定向:。
答案 1 :(得分:2)