2009-04-28 51 views
71

Làm cách nào để có tên người dùng/tên đăng nhập trong Java?Nhận tên người dùng đăng nhập bằng java

Đây là mã tôi đã cố gắng ...

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 đề.

+2

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

+0

Không thể hiểu bất cứ điều gì khi không có chi tiết nào được đăng –

+0

Xin lỗi các bạn. Tôi mới sử dụng Java và bây giờ hơi khó hiểu. –

Trả lời

175
System.getProperty("user.name") 
+3

+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 –

+0

Cảm ơn!Tôi đến từ Flash/actionscript ... vì vậy tôi đã có một looooooot để trang trải :) –

+1

Đố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. –

27

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() 
+37

Mã này đi ngược lại triết lý viết của Java viết một lần, chạy bất cứ nơi nào (giới thiệu mã cụ thể của hệ điều hành), và thứ hai, nó tạo ra sự phụ thuộc vào việc thực hiện Java của Sun. –

+12

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ả. –

+6

@ChinmayKanchi: Nếu không có tên người dùng, thì thuộc tính 'user.name' chỉ nên là rỗng. Tôi đồng ý với @JinKim, đừng viết những thứ phụ thuộc vào hệ điều hành. –

14

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ể bị giả mạo: C: \ thiết 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ý. info source

+0

Khá tiện lợi +1! Cảm ơn! –

+2

Đây không phải là giải pháp hoàn chỉnh vì nó chỉ hoạt động trong Windows. –

+1

Điều này có thể bị giả mạo không, ví dụ: với trình nạp lớp tùy chỉnh hoặc triển khai tuỳ 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

13

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

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)); 
} 
+0

Sử dụng tốt sự phản chiếu :) – Zizouz212

+3

Điều này sẽ phá vỡ trên Windows vì phương pháp trên NTSystem để lấy tên người dùng là "getName()" chứ 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ù? –

2

Các 'đặt Username = "Tên đăng nhập"' là một override tạm thời mà chỉ tồn tại miễn là các cửa sổ cmd vẫn còn lên, một khi nó bị tiêu diệ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.

1

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

Trong 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ủ lưu trữ! Tôi đang nói một lần nữa! Hoạt động trên WINDOWS!

+0

Điều gì về 'System.getenv (" username ")'? :) –

5

Sử dụng JNA đơn giản của 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

+0

Đ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 vấn đề liên quan