Java'da kullanıcı adı alın


92

Java'da kullanıcı adını / giriş adını nasıl alabilirim?

Bu denediğim kod ...

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());
}

SecurityExceptionBu kodu çalıştırmayı denediğimde bir alıyorum. Lütfen birisi bana doğru yönde gidip gitmediğimi söyleyebilir ve sorunu anlamama yardım edebilir mi?


3
Seni yanlış anlamaktan korkuyorum ama sorunuzu anlamıyorum. Hangi giriş kullanıcı adı? Windows / GNU Linux girişi? Bir web sunucusunda temel kimlik doğrulama?
guerda

Hiçbir ayrıntı gönderilmediğinde hiçbir şeyi anlamak imkansız
matt b

Üzgünüm beyler. Java'da yeniyim ve şu anda mantıklı olmak biraz zor.
George Profenza

Yanıtlar:


225
System.getProperty("user.name")

4
+1, VM'nin başlatıldığı birçok bilgi almak için System.properties dosyasını yazdırabilirsiniz
Markus Lausberg

3
Benim için bu, VM'yi çalıştıran kullanıcının adını yazdırır. Java uygulamasında oturum açmış kullanıcı değil.
Tom Brito

1
Bu, yaygın olarak bulunabilen bir üçüncü taraf kitaplığında herhangi bir yerde tanımlanmış mı? Ya da user.nameözellik adı için JDK tarafından sağlanan sınıfların herhangi bir yerinde tanımlanmış bir sabit var mı?
Jeff Evans

29

Unix'te:

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

Windows'ta:

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

Solaris'te:

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

49
Bu kod, Java'nın bir kez yazma, herhangi bir yerde çalıştırma (işletim sistemine özgü kodun tanıtımı) felsefesine aykırıdır ve ikinci olarak, Sun'ın Java uygulamasına bağımlılık yaratır.
Jin Kim

14
Kullanıcı adını almaya çalışmak, tanımı gereği platforma özgüdür. Tek kullanıcılı bir sistemde çalışan bir JVM'nin bir kullanıcı adı hiç olmayabilir.
Chinmay Kanchi

8
@ChinmayKanchi: Eğer kullanıcı adı yoksa, user.nameözellik sadece boş olmalıdır. @JinKim'e katılıyorum, işletim sistemine bağlı şeyler yazmayın.
Bay Lance E Sloan

2
user.name komut satırından ayarlanabilir, dolayısıyla kullanım durumunun ne olduğuna çok bağlıdır
Alice Purcell

3
Com.sun paketleri altındaki sınıflar bir geliştirici tarafından kullanılmamalıdır. İçseldirler ve gelecekte değişebilir.
CHiRo79

17

@newacct'in cevabından esinlenerek , herhangi bir platformda derlenebilen bir kod:

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

İyi bir yansıma kullanımı :)
Zizouz212

5
NTSystem üzerinde kullanıcı adını alma yöntemi "getUsername ()" değil "getName ()" olduğundan bu, Windows'ta bozulur. Sanırım daha fazla kontrol yapabilir ve ardından doğru yöntemi çağırabilirsiniz. Tuhaf, bu JRE tarafından işletim sisteminden bağımsız bir mekanizmaya dönüştürülmüyor mu?
John Mark Scarborough

1
com.sunSınıflar Java 9 + varsayılan olarak erişilemez. Bu çözüm onun için işe yaramayacak.
Thunderforge

Yeni bir API eklenmedikçe Java 9'da çalışacak tek şeyin dfa'nın çözümü olacağını düşünüyorum .
Thunderforge

15

System.getProperty ("user.name"), bu ortam değişkeni sahte olabileceği için iyi bir güvenlik seçeneği değildir: C: \ set USERNAME = "Joe Doe" java ... // size System.getProperty ("kullanıcı. name ") Yapmalısın:

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

JDK 1.5 ve üstü.

Bir uygulama içinde kullanıyorum ve imzalanması gerekiyor. bilgi kaynağı


4
Bu, yalnızca Windows altında çalıştığı için tam bir çözüm değildir.
Bay Lance E Sloan

1
Bu da, örneğin özel bir sınıf yükleyici veya com.sun.security.auth.module.NYSystemsınıf yolunda daha yüksek özel bir uygulama ile sahte olabilir mi? Java çalışma zamanının bu tür istismarlara karşı önlemeye çalışıp çalışmadığını bilmiyorum, ancak potansiyel olarak kötü niyetli istemcinin erişemeyeceği bir kutuda kod çalıştırmanın dışında, onu 'güvenli' hale getirmenin şüphesiz bir yolu olacağını düşünmüyorum. .
bacar

4
PowerMock (özel bir sınıf yükleyici kullandığına inanıyorum) kullanarak NTSystem.getName () uygulamasını başarıyla değiştirmeyi başardım, bu nedenle 'güvenlik' için gerçekten böyle bir şeye güvenemezsiniz ... ancak bilmiyorum uygulama dünyasında işler nasıl. Birisi özel sistem özellikleri sağlayabilirse, özel sınıflar veya özel sınıf yükleyiciler de sağlayabileceklerini düşünmüştüm.
bacar

1
-1 Çünkü yalnızca Windows'ta çalışır. Bunu KULLANMAMALISINIZ.
stommestack

@bacar: Buna güvenmemeli ve birinin oldukça güvenli olduğunu düşünmemesine katılıyorum. Ama bence güvenlik "seviyeler" ile ilgilidir. Ve ortam değişkenini değiştirmek, bir yönteme güç sağlamaktan çok daha kolaydır. Ortam değişkeni yerine NTSystem kullanan BT dışı bir şirkette, onu alt edebilecek insan sayısı yarıdan daha fazladır: P. Böylece biraz daha fazla güvenlik elde edersiniz, ancak buna karşılık yolda bazı java kurallarını kaybedersiniz.
Calon

6

JNA'yı kullanmak çok basit:

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


1
Etki alanı kullanıcısı olarak oturum açtıysanız, ancak aynı adda yerel bir kullanıcı varsa bu işe yaramaz. getAccountByName yerel kullanıcı için bilgi döndürecektir.
Dave

2

'Set adı = 'Kullanıcı adı'' Sadece öldürdü sonra cmd pencereler değişken değerini kaybeder, hâlâ yayında olduğu sürece var olduğunu geçici sayar. Bence

System.getProperty ("kullanıcı.adı");

hala kısa ve kesin bir koddur.


1

System.getenv().get("USERNAME"); - pencerelerde çalışır!

Ortam özelliklerinde, bilgisayar ve ana bilgisayar hakkında ihtiyacınız olan bilgilere sahipsiniz! Tekrar söylüyorum! WINDOWS'ta çalışıyor!


Peki ya System.getenv("username")? :)
ROMANIA_engineer

Doens'ın çalışması, eğer VM - örneğin tomcat - bir Windows hizmeti olarak başlatılırsa, ana bilgisayar adını içeren bir şey döndürür
Deepak

0

Aşağıda YALNIZCA WINDOWS için bir çözüm bulunmaktadır

Uygulamanın (Tomcat gibi) bir Windows hizmeti olarak başlatıldığı durumlarda, System.getProperty ("user.name") veya System.getenv (). Get ("USERNAME") hizmeti başlatan kullanıcıyı döndürür, mevcut oturum açmış kullanıcı adı.

Ayrıca Java 9'da NTSystem vb. Sınıflara erişilemez

Windows için geçici çözüm: Wmic'i kullanabilirsiniz , bu nedenle aşağıdaki komutu çalıştırmanız gerekir

wmic ComputerSystem get UserName

Varsa, bu formun çıktısını döndürür:

UserName
{domain}\{logged-in-user-name}

Not: Windows için önek olarak cmd / c kullanmanız gerekir, bu nedenle aşağıda örnek olarak kaba bir program verilmiştir:

    Process exec = Runtime.getRuntime().exec("cmd /c wmic ComputerSystem get UserName".split(" "));
    System.out.println(exec.waitFor());
    try (BufferedReader bw = new BufferedReader(new InputStreamReader(exec.getInputStream()))) {
        System.out.println(bw.readLine() + "\n" + bw.readLine()+ "\n" + bw.readLine());
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.