我有两个代表用户的字符串和该用户的密码。我想在Unix环境中检查这是否是有效的身份验证对。
我考虑过运行sudo bash命令来验证Java代码内部,并查看执行的命令的退出值是否等于0.
但是我无法做到这一点。
public class Test{
public static void main(String args[]){
String user = "user";
String pass = "pass\n";
try{
Process proc = new ProcessBuilder(
"/bin/sh","-c","sudo","-S","su",user).start();
OutputStream os = proc.getOutputStream();
os.write(pass.getBytes());
os.flush();
os.close();
try{
System.out.println(proc.waitFor());
} catch ( InterruptedException e ){
e.printStackTrace();
}
} catch ( IOException e ){
e.printStackTrace();
}
}
}
此代码打印1作为退出代码。 我真的尝试过我能在网上找到的所有内容,但我仍然需要弄清楚如何正常工作。
任何人都可以帮助我吗? THX
答案 0 :(得分:0)
sudo
询问当前用户的密码,即启动java进程的用户,因此不会检查user
的密码。
而不是"/bin/sh","-c","sudo","-S","su",user).start();
尝试"/bin/sh","-c","su",user).start();
。这只会尝试切换到该用户,因此会询问user
的密码。
答案 1 :(得分:0)
基于su.c源代码I've wrote a simple java program,使用JNA进行用户凭据验证。它必须适用于所有具有libc和crypt库的基于Unix的发行版,如下所示:
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
System.out.println("type the user");
final String user = scanner.nextLine();
System.out.println("type password");
final String password = scanner.nextLine();
System.out.println("RESULT\n===========================================");
final SPassword passwd = CLibrary.INSTANCE.getspnam(user);
if(passwd == null){
throw new RuntimeException(String.valueOf(Native.getLastError()));
}
final String encrypted = Crypt.INSTANCE.crypt(password, passwd.sp_pwdp);
System.out.printf("matches=%b%n", encrypted.equals(passwd.sp_pwdp));
}
interface Crypt extends Library {
Crypt INSTANCE = Native.loadLibrary("crypt", Crypt.class);
String crypt(String key, String salt);
}
interface CLibrary extends Library {
CLibrary INSTANCE = Native.loadLibrary("c", CLibrary.class);
Password getpwnam(String username);
SPassword getspnam(String username);
}
测试
git clone https://github.com/mageddo/java-native-examples.git &&\
cd java-native-examples && git checkout -f ef4eb3e &&\
./gradlew clean build fatjar &&\
sudo java -jar build/libs/java-native-examples-all-*.jar
出
type the user
elvis
type password
*********
RESULT
===========================================
matches=true
Obs :缺点是这个应用程序必须以root或sudo用户身份运行,我无法解决这个问题,无论如何我认为一旦 su 命令就可以出于安全原因(如果在您的上下文中存在问题),我建议将此功能与应用程序隔离,然后通过REST,Soap,TCP等来调用它。这样,您当前的应用程序将不需要以root身份运行。
如果您愿意,可以用apache commons codec lib function替换执行相同操作的crypt函数。