Câu hỏi Nhận tên người dùng đăng nhập bằng java


Làm thế nào tôi có thể lấy tên người dùng / tên đăng nhập trong Java?

Đây là mã tôi đã thử ...

try{
    LoginContext lc = new LoginContext(appName,new TextCallbackHandler());
    lc.login();
    Subject subject = lc.getSubject();
    Principal principals[] = (Principal[])subject.getPrincipals().toArray(new Principal[0]);

    for (int i=0; i<principals.length; i++) {
        if (principals[i] instanceof NTUserPrincipal || principals[i] instanceof UnixPrincipal) {
            String loggedInUserName = principals[i].getName();
        }
    }

}
catch(SecurityException se){
    System.out.println("SecurityException: " + se.getMessage());
}

Tôi nhận được một SecurityException khi tôi cố gắng chạy mã này. Có thể ai đó vui lòng cho tôi biết tôi có đi đúng hướng hay không và giúp tôi hiểu vấn đề.


75
2018-04-28 12:08


gốc


Tôi sợ hiểu lầm bạn, nhưng tôi không hiểu câu hỏi của bạn. Tên đăng nhập nào? Đăng nhập Windows / GNU Linux? Xác thực cơ bản trên máy chủ web? - guerda
Không thể hiểu bất cứ điều gì khi không có chi tiết nào được đăng - matt b
Xin lỗi các bạn. Tôi mới sử dụng Java và bây giờ hơi khó hiểu. - George Profenza


Các câu trả lời:


System.getProperty("user.name")

183
2018-04-28 12:11



+1 bạn có thể in System.properties để nhận được rất nhiều thông tin VM được khởi tạo với - Markus Lausberg
Cảm ơn! Tôi đến từ Flash / actionscript ... vì vậy tôi đã có một looooooot để trang trải :) - George Profenza
Đối với tôi điều này in tên của người dùng thực hiện VM. Không phải người dùng đã đăng nhập trên ứng dụng java. - Tom Brito


trong Unix:

new com.sun.security.auth.module.UnixSystem().getUsername()

trong Windows:

new com.sun.security.auth.module.NTSystem().getName()

trong Solaris:

new com.sun.security.auth.module.SolarisSystem().getUsername()

30
2018-04-28 23:35



Mã này đi ngược lại triết lý của Java viết một lần, chạy bất cứ nơi nào (giới thiệu mã hệ điều hành cụ thể), và thứ hai, nó tạo ra một sự phụ thuộc vào việc thực hiện Java của Sun. - Jin Kim
Cố gắng để có được tên người dùng là theo định nghĩa nền tảng cụ thể. Một JVM chạy trên một hệ thống người dùng đơn lẻ có thể không có tên người dùng nào cả. - Chinmay Kanchi
@ChinmayKanchi: Nếu không có tên người dùng, thì user.name tài sản chỉ nên là null. Tôi đồng ý với @JinKim, đừng viết những thứ phụ thuộc vào hệ điều hành. - L S
user.name có thể được đặt trên dòng lệnh, vì vậy nó phụ thuộc rất nhiều vào trường hợp sử dụng là gì - Alice Purcell
Các lớp trong gói com.sun không nên được nhà phát triển sử dụng. Chúng là nội bộ và có thể thay đổi trong tương lai. - CHiRo79


System.getProperty ("user.name") không phải là một tùy chọn bảo mật tốt vì biến môi trường đó có thể được giả mạo: C: \ set USERNAME = "Joe Doe" java ... // sẽ cung cấp cho bạn System.getProperty ("user.name") Bạn nên làm:

com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem();
System.out.println(NTSystem.getName());

JDK 1.5 và cao hơn.

Tôi sử dụng nó trong một applet, và nó phải được ký kết. nguồn thông tin


15
2018-02-18 16:48



Khá tiện lợi +1! Cảm ơn! - George Profenza
Đây không phải là giải pháp hoàn chỉnh vì nó chỉ hoạt động trong Windows. - L S
Điều này có thể được giả mạo quá không, ví dụ: với trình nạp lớp tùy chỉnh hoặc triển khai tùy chỉnh com.sun.security.auth.module.NYSystem cao hơn trong classpath? Tôi không biết liệu thời gian chạy Java có cố gắng ngăn chặn việc khai thác như vậy hay không, nhưng tôi không nghĩ rằng sẽ có bất kỳ cách nào không an toàn để làm cho nó 'an toàn' ngoại trừ việc chạy mã trên một hộp không thể truy cập được vào máy khách có nguy cơ độc hại . - bacar
Tôi chỉ quản lý thành công để thay thế việc thực hiện NTSystem.getName () bằng PowerMock (mà tôi tin là sử dụng trình nạp lớp tùy chỉnh), vì vậy bạn thực sự không thể dựa vào thứ gì đó như thế này cho 'bảo mật' ... tuy nhiên tôi không biết mọi thứ trong thế giới applet như thế nào. Tôi đã nghĩ rằng nếu ai đó có thể cung cấp các thuộc tính hệ thống tùy chỉnh thì họ cũng có thể cung cấp các lớp tùy chỉnh hoặc trình nạp lớp tùy chỉnh. - bacar
-1 Bởi vì nó chỉ hoạt động trên Windows. Bạn KHÔNG nên sử dụng điều này. - Jop V.


lấy cảm hứng từ @newacctCâu trả lời, một mã có thể được biên dịch trong bất kỳ nền tảng nào:

String osName = System.getProperty( "os.name" ).toLowerCase();
String className = null;
String methodName = "getUsername";

if( osName.contains( "windows" ) ){
    className = "com.sun.security.auth.module.NTSystem";
    methodName = "getName";
}
else if( osName.contains( "linux" ) ){
    className = "com.sun.security.auth.module.UnixSystem";
}
else if( osName.contains( "solaris" ) || osName.contains( "sunos" ) ){
    className = "com.sun.security.auth.module.SolarisSystem";
}

if( className != null ){
    Class<?> c = Class.forName( className );
    Method method = c.getDeclaredMethod( methodName );
    Object o = c.newInstance();
    System.out.println( method.invoke( o ) );
}

14
2018-06-05 15:37



Sử dụng tốt sự phản chiếu :) - Zizouz212
Điều này sẽ phá vỡ trên Windows kể từ khi phương pháp trên NTSystem để có được tên người dùng là "getName ()" và không phải "getUsername ()". Tôi cho rằng bạn có thể kiểm tra thêm và sau đó gọi đúng phương pháp. Bizarre này không phải là trừu tượng vào một cơ chế bất khả tri hệ điều hành bởi JRE mặc dù? - John Mark Scarborough


Sử dụng JNA của nó đơn giản:

String username = Advapi32Util.getUserName();
System.out.println(username);

Advapi32Util.Account account = Advapi32Util.getAccountByName(username);
System.out.println(account.accountType);
System.out.println(account.domain);
System.out.println(account.fqn);
System.out.println(account.name);
System.out.println(account.sidString);

https://github.com/java-native-access/jna


6
2017-11-18 15:53



Điều này không hoạt động nếu bạn đăng nhập với tư cách là người dùng miền nhưng cũng có một người dùng cục bộ có cùng tên. getAccountByName sẽ trả về thông tin cho người dùng cục bộ. - Dave


Các 'set Username = "Username" là một ghi đè tạm thời chỉ tồn tại miễn là các cửa sổ cmd vẫn đang hoạt động, khi nó bị tắt, biến mất giá trị. Vì vậy, tôi nghĩ rằng

System.getProperty ("user.name");

vẫn là một mã ngắn và chính xác để sử dụng.


2
2018-06-01 13:30





System.getenv().get("USERNAME");  - hoạt động trên các cửa sổ!

Trong các thuộc tính môi trường, bạn có thông tin bạn cần về máy tính và máy chủ! Tôi đang nói một lần nữa! Hoạt động trên WINDOWS!


1
2017-08-11 14:11



Thế còn System.getenv("username") ? :) - ROMANIA_engineer