Javaでログインユーザー名を取得する


92

Javaでユーザー名/ログイン名を取得するにはどうすればよいですか?

これは私が試したコードです...

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

私が取得SecurityException私はこのコードを実行しようとします。誰かが私が正しい方向に進んでいるかどうか教えてください、そして私が問題を理解するのを助けてください。


3
あなたを誤解するのを恐れていますが、私はあなたの質問を理解していません。どのログインユーザー名?Windows / GNU Linuxログイン?Webサーバーでの基本認証?
ゲルダ

詳細が投稿されていないと、何も理解できません
matt b

すみません。私はJavaを初めて使用するので、今では意味がわかりません。
ジョージプロフェンツァ2009

回答:


224
System.getProperty("user.name")

4
+1 System.propertiesを印刷して、VMが初期化された多くの情報を取得できます
Markus Lausberg

3
私にとっては、これはVMを実行しているユーザーの名前を出力します。Javaアプリケーションにログインしているユーザーではありません。
トム・ブリト

1
これは広く利用可能なサードパーティライブラリのどこかに定義されていますか?または、user.nameプロパティ名のJDK提供クラスのどこかに定数が定義されていますか?
ジェフエヴァンス

29

Unixの場合:

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

Windowsの場合:

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

Solarisの場合:

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

49
このコードは、Javaの1回の書き込みの哲学に反し、どこでも実行でき(OS固有のコードの紹介)、次に、SunのJavaの実装に依存します。
ジンキム

14
ユーザー名を取得しようとするのは、プラットフォーム固有の定義です。シングルユーザーシステムで実行されているJVMには、ユーザー名がまったくない場合があります。
Chinmay Kanchi、2010

8
@ChinmayKanchi:ユーザー名がない場合、user.nameプロパティはnullにする必要があります。@JinKimに同意します。OSに依存するものは記述しないでください。
LS

2
user.nameはコマンドラインで設定できるため、ユースケースが何であるかに大きく依存します
Alice Purcell

3
com.sunパッケージの下のクラスは、開発者が使用するべきではありません。これらは内部用であり、将来変更される可能性があります。
CHiRo79 2014

17

@newacctの回答に触発され、任意のプラットフォームでコンパイルできるコード:

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

リフレクションの活用:)
Zizouz212

5
NTSystemでユーザー名を取得するメソッドが「getName()」であり、「getUsername()」ではないため、これはWindowsでは機能しません。さらにチェックしてから、適切なメソッドを呼び出すことができると思います。奇妙なことに、これはJREによってOSに依存しないメカニズムに抽象化されていませんか?
ジョンマークスカーバラ

1
com.sunクラスは、Java 9+で、デフォルトではアクセスできません。このソリューションは機能しません。
Thunderforge 2018

新しいAPIが追加されない限り、Java 9で機能するのはdfaのソリューションだけだと思います。
Thunderforge

15

System.getProperty( "user.name")は、その環境変数が偽造される可能性があるため、適切なセキュリティオプションではありません。C:\ set USERNAME = "Joe Doe" java ... // System.getProperty( "user。名前 ")すべきこと:

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

JDK 1.5以降。

アプレット内で使用し、署名が必要です。 情報源


4
これはWindowsでのみ機能するため、完全なソリューションではありません。
LS

1
これもまた、たとえばカスタムクラスローダーやcom.sun.security.auth.module.NYSystemクラスパスの上位のカスタム実装を使用して偽装できますか?Javaランタイムがそのようなエクスプロイトを防止しようとするかどうかはわかりませんが、悪意のある可能性のあるクライアントがアクセスできないボックスでコードを実行する以外は、「安全」にするための偽りのない方法はないと思います。
bacar

4
私はPowerMock(カスタムクラスローダーを使用していると思います)を使用してNTSystem.getName()の実装を正常に置き換えることができたので、「セキュリティ」のためにこのようなものに本当に頼ることはできません...しかし、私は知りませんアプレットの世界の状況。誰かがカスタムシステムプロパティを提供できれば、カスタムクラスやカスタムクラスローダーも提供できると思いました。
bacar

1
-1 Windowsでのみ機能するため。これは使用しないでください。
stommestack 2013

@bacar:私は同意します、これに頼るべきではなく、かなり安全だと思います。しかし、私の意見では、セキュリティは「レベル」に関するものです。また、メソッドをパワーモックするよりも環境変数を変更する方が簡単です。IT以外の企業では、環境変数ではなくNTSystemを使用しているため、環境変数を引き出すことができる人の数は半分以上になります。そのため、セキュリティは少し向上しますが、今度はいくつかのJavaの規則が失われます。
カロン2014年

6

JNAを使用するのは簡単です。

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
これは、ドメインユーザーとしてログインしている場合は機能しませんが、同じ名前のローカルユーザーもいます。getAccountByNameは、ローカルユーザーの情報を返します。
デイブ

2

「を設定ユーザー名= 『ユーザ名は、』」それだけが殺された後、CMDウィンドウが変数の値を失い、アップまだある限り存在することを一時的に無効です。だから私は思う

System.getProperty( "user.name");

まだ使用する短くて正確なコードです。


1

System.getenv().get("USERNAME"); -Windowsで動作します!

環境プロパティには、コンピューターとホストについて必要な情報があります。もう一度言います!WINDOWSで動作します!


どうSystem.getenv("username")ですか?:)
ROMANIA_engineer 2017

VM(Tomcatなど)がWindowsサービスとして開始されている場合、Doensは動作し、ホスト名を含む何かを返します
Deepak

0

以下は、WINDOWSのみのソリューションです。

アプリケーション(Tomcatなど)がWindowsサービスとして開始されている場合、System.getProperty( "user.name")またはSystem.getenv()。get( "USERNAME")は、サービスではなく、サービスを開始したユーザーを返します。現在ログインしているユーザー名。

また、Java 9ではNTSystemなどのクラスにアクセスできません。

Windowsの回避策:wmicを使用できるため、以下のコマンドを実行する必要があります

wmic ComputerSystem get UserName

利用可能な場合、これはフォームの出力を返します:

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

注:Windowsの場合は、cmd / cをプレフィックスとして使用する必要があるため、以下は大まかなプログラムの例です。

    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());
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.