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 로그인? 웹 서버의 기본 인증?
guerda

세부 사항이 게시되지 않으면 아무것도 이해할 수 없습니다
matt b

죄송합니다. 저는 Java를 처음 접했고 지금은 이해하기가 조금 어렵습니다.
George Profenza

답변:


225
System.getProperty("user.name")

4
+1 System.properties를 인쇄하여 VM이 초기화 된 많은 정보를 얻을 수 있습니다.
Markus Lausberg

3
나를 위해 이것은 VM을 실행하는 사용자의 이름을 인쇄합니다. Java 애플리케이션에 로그인 한 사용자가 아닙니다.
Tom Brito

1
널리 사용 가능한 타사 라이브러리의 어느 곳에서나 정의됩니까? 아니면 user.name속성 이름에 대해 JDK 제공 클래스에 상수가 정의되어 있습니까?
Jeff Evans

29

유닉스에서 :

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
이 코드는 한 번만 작성하고 어디에서나 실행 (OS 별 코드 소개)이라는 Java의 철학에 위배되며 두 번째로 Sun의 Java 구현에 대한 종속성을 생성합니다.
Jin Kim

14
사용자 이름을 얻으려는 시도는 정의에 따라 플랫폼별로 다릅니다. 단일 사용자 시스템에서 실행되는 JVM에는 사용자 이름이 전혀 없을 수 있습니다.
Chinmay Kanchi

8
@ChinmayKanchi : 사용자 이름이 없으면 user.name속성은 null이어야합니다. @JinKim에 동의하고 OS에 의존하는 내용을 작성하지 마십시오.
Mr. Lance E Sloan

2
아주 많이 사용 사례가 무엇인지 달려 있으므로 user.name은 명령 줄에서 설정할 수 있습니다
앨리스 퍼셀을

3
com.sun 패키지의 클래스는 개발자가 사용해서는 안됩니다. 내부적이며 향후 변경 될 수 있습니다.
CHiRo79

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에서 사용자 이름을 가져 오는 방법이 "getUsername ()"이 아니라 "getName ()"이기 때문에 Windows에서 중단됩니다. 추가 검사를 수행 한 다음 올바른 메서드를 호출 할 수 있다고 가정합니다. JRE에 의해 OS와 무관 한 메커니즘으로 추상화되지 않은 것이 기괴한가요?
John Mark Scarborough

1
com.sun클래스는 자바 9+에서 기본적으로 액세스 할 수 없습니다. 이 솔루션은 작동하지 않습니다.
Thunderforge

새로운 API가 추가되지 않는 한 Java 9에서 작동하는 유일한 것은 dfa의 솔루션 이라고 생각합니다 .
Thunderforge

15

System.getProperty ( "user.name")는 환경 변수가 위조 될 수 있으므로 좋은 보안 옵션이 아닙니다. C : \ set USERNAME = "Joe Doe"java ... // System.getProperty ( "user. name ")해야 할 일 :

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

JDK 1.5 이상.

애플릿 내에서 사용하고 서명해야합니다. 정보 출처


4
Windows에서만 작동하므로 완전한 솔루션은 아닙니다.
Mr. Lance E Sloan

1
예를 들어 사용자 정의 클래스 로더 또는 com.sun.security.auth.module.NYSystem클래스 경로에서 상위 의 사용자 정의 구현을 사용하여 이것도 스푸핑 될 수 있습니까? Java 런타임이 이러한 악용을 방지하려고 시도하는지 여부는 알 수 없지만 잠재적으로 악의적 인 클라이언트가 액세스 할 수없는 상자에서 코드를 실행하는 것 외에는 '안전'하게 만드는 가짜 방법이 없을 것이라고 생각합니다. .
bacar 2012-08-13

4
PowerMock (사용자 정의 클래스 로더를 사용한다고 생각)을 사용하여 NTSystem.getName () 구현을 성공적으로 교체했기 때문에 '보안'을 위해 이와 같은 것에 의존 할 수는 없습니다 ... 그러나 모르겠습니다. 애플릿 세계의 상황. 누군가 사용자 지정 시스템 속성을 제공 할 수 있다면 사용자 지정 클래스 또는 사용자 지정 클래스 로더도 제공 할 수 있다고 생각했을 것입니다.
bacar 2012-08-13

1
-1 Windows에서만 작동하기 때문입니다. 이것을 사용해서는 안됩니다.
stommestack 2013-09-16

@bacar : 동의합니다. 이것에 의존해서는 안되며 하나는 꽤 안전하다고 생각합니다. 그러나 제 생각에는 보안은 "수준"에 관한 것입니다. 그리고 메서드를 파워 모킹하는 것보다 환경 변수를 변경하는 것이 더 쉽습니다. 환경 변수가 아닌 NTSystem을 사용하는 비 IT 회사에서는 그것을 뽑을 수있는 사람들의 양을 절반 이상으로 줄입니다. 그래서 당신은 좀 더 많은 보안을 얻지 만, 길에서 자바 규칙을 잃게됩니다.
Calon 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은 로컬 사용자에 대한 정보를 반환합니다.
Dave

2

'설정 사용자 이름 = "사용자 이름"' 에만 전원이 살해되면 cmd를 창문 변수 값을 잃게, 최대 여전히만큼 존재하는 임시 재이다. 그래서 나는

System.getProperty ( "user.name");

여전히 짧고 정확한 코드입니다.


1

System.getenv().get("USERNAME"); -창문에서 작동합니다!

환경 속성에는 컴퓨터와 호스트에 대해 필요한 정보가 있습니다! 나는 다시 말하고있다! WINDOWS에서 작동합니다!


어때 System.getenv("username")? :)
ROMANIA_engineer

VM의 경우 Doens '작업 - 말 바람둥이가 - Windows 서비스로 시작, 그것은 호스트 이름이 포함 뭔가 반환
디팍

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.