如何判断账号运行java申请是否'SYSTEM'
How to determine if account running java application is 'SYSTEM'
如何检查我的 Java 应用程序是否 运行 宁作为“系统”/“本地系统”(如 Windows 服务列表中所示)?
我试过用这个:
System.out.println("Running with user: " + System.getenv().get("USERDOMAIN") + "\" + System.getenv().get("USERNAME"));
...不过好像returnDOMAIN\COMPUTERNAME
根据程序所在运行。所以它可以像 DOMAIN1\COMPUTER1
而在其他地方它是 FOO\SERVER451
并且两者仍然表示“SYSTEM”帐户。
关于背景信息,我的 Java 应用程序被包装到 Windows 服务 'Apache Commons Daemon Service Runner' 并且默认情况下它将 运行 作为“本地系统”(同样的方式如示例图片所示)。
我真的很想简化我的代码以根据用户类型打印 SYSTEM
或 MYDOMAIN\JackTheUser
...有没有办法用 Java 来实现?
编辑 20/12/02:
这就是我在 SO 军队努力寻找正确答案的同时所做的事情:
Main:
String username = System.getenv().get("USERNAME");
String userdomain = System.getenv().get("USERDOMAIN");
String servername = getComputerName();
if (username.equalsIgnoreCase((servername + "$"))) {
System.out.println("Running with user: 'Local System'("
+ userdomain + "\" + username + ")");
} else {
System.out.println("Running with user: '" + userdomain + "\"
+ username + "'");
}
Methods:
private static String getComputerName() {
Map<String, String> env = System.getenv();
if (env.containsKey("COMPUTERNAME"))
return env.get("COMPUTERNAME");
else if (env.containsKey("HOSTNAME"))
return env.get("HOSTNAME");
else
return "Unknown Host name";
}
打印:
Running with user: 'MYDOMAIN\jokkeri'
或 Running with user: 'Local System'(MYSERVER\SERVER_1$)
(不是一个完美的解决方案,我敢肯定在很多情况下它都行不通,但这是一个起点)
EDIT2 20/12/02:
从超级用户的这个线程中找到了一些关于 SYSTEM 帐户的有用信息:https://superuser.com/questions/265216/windows-account-ending-with
这是迄今为止我能想到的最好的
private static final String APP_NAME = "Some App";
private static final Configuration CONFIG = new Configuration() {
public @Override AppConfigurationEntry[] getAppConfigurationEntry(String name) {
return name.equals(APP_NAME)?
new AppConfigurationEntry[] { new AppConfigurationEntry(
"com.sun.security.auth.module.NTLoginModule",
LoginModuleControlFlag.REQUIRED, Collections.emptyMap())}:
null;
}
};
static final boolean DEBUG = true;
public static void main(String[] args) throws LoginException {
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
boolean isSystem = false;
try {
for(Principal p: subject.getPrincipals()) {
if(DEBUG) System.out.println(p);
if(p.toString().equals("NTSidUserPrincipal: S-1-5-18")) {
isSystem = true;
if(DEBUG) System.out.println("\tit's SYSTEM");
}
}
}
finally { lc.logout(); }
}
如 this answer 中所述,SYSTEM 是一组可以附加到不同帐户的权限。该代码遍历与当前帐户关联的所有主体并测试众所周知的 SYSTEM。
但如果您只对可打印的用户名感兴趣,您可以检查 NTUserPrincipal。
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
String name = System.getProperty("user.name"); // just a fall-back
for(Principal p: subject.getPrincipals()) {
if(p.toString().startsWith("NTUserPrincipal: ")) {
name = p.getName();
break;
}
}
System.out.println("Hello " + name);
}
finally { lc.logout(); }
如果您可以直接依赖 com.sun.security.auth
包(或 Java 9+ 中的 jdk.security.auth
模块),则可以直接使用特定的主体类型
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
boolean system = false;
for(NTSidUserPrincipal p: subject.getPrincipals(NTSidUserPrincipal.class)) {
if(p.getName().equals("S-1-5-18")) {
system = true;
break;
}
}
Set<NTUserPrincipal> up = subject.getPrincipals(NTUserPrincipal.class);
String name = up.isEmpty()?
System.getProperty("user.name"): up.iterator().next().getName();
System.out.println("Hello " + name+(system? " *": ""));
}
finally { lc.logout(); }
如何检查我的 Java 应用程序是否 运行 宁作为“系统”/“本地系统”(如 Windows 服务列表中所示)?
我试过用这个:
System.out.println("Running with user: " + System.getenv().get("USERDOMAIN") + "\" + System.getenv().get("USERNAME"));
...不过好像returnDOMAIN\COMPUTERNAME
根据程序所在运行。所以它可以像 DOMAIN1\COMPUTER1
而在其他地方它是 FOO\SERVER451
并且两者仍然表示“SYSTEM”帐户。
关于背景信息,我的 Java 应用程序被包装到 Windows 服务 'Apache Commons Daemon Service Runner' 并且默认情况下它将 运行 作为“本地系统”(同样的方式如示例图片所示)。
我真的很想简化我的代码以根据用户类型打印 SYSTEM
或 MYDOMAIN\JackTheUser
...有没有办法用 Java 来实现?
编辑 20/12/02: 这就是我在 SO 军队努力寻找正确答案的同时所做的事情:
Main:
String username = System.getenv().get("USERNAME");
String userdomain = System.getenv().get("USERDOMAIN");
String servername = getComputerName();
if (username.equalsIgnoreCase((servername + "$"))) {
System.out.println("Running with user: 'Local System'("
+ userdomain + "\" + username + ")");
} else {
System.out.println("Running with user: '" + userdomain + "\"
+ username + "'");
}
Methods:
private static String getComputerName() {
Map<String, String> env = System.getenv();
if (env.containsKey("COMPUTERNAME"))
return env.get("COMPUTERNAME");
else if (env.containsKey("HOSTNAME"))
return env.get("HOSTNAME");
else
return "Unknown Host name";
}
打印:
Running with user: 'MYDOMAIN\jokkeri'
或 Running with user: 'Local System'(MYSERVER\SERVER_1$)
(不是一个完美的解决方案,我敢肯定在很多情况下它都行不通,但这是一个起点)
EDIT2 20/12/02: 从超级用户的这个线程中找到了一些关于 SYSTEM 帐户的有用信息:https://superuser.com/questions/265216/windows-account-ending-with
这是迄今为止我能想到的最好的
private static final String APP_NAME = "Some App";
private static final Configuration CONFIG = new Configuration() {
public @Override AppConfigurationEntry[] getAppConfigurationEntry(String name) {
return name.equals(APP_NAME)?
new AppConfigurationEntry[] { new AppConfigurationEntry(
"com.sun.security.auth.module.NTLoginModule",
LoginModuleControlFlag.REQUIRED, Collections.emptyMap())}:
null;
}
};
static final boolean DEBUG = true;
public static void main(String[] args) throws LoginException {
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
boolean isSystem = false;
try {
for(Principal p: subject.getPrincipals()) {
if(DEBUG) System.out.println(p);
if(p.toString().equals("NTSidUserPrincipal: S-1-5-18")) {
isSystem = true;
if(DEBUG) System.out.println("\tit's SYSTEM");
}
}
}
finally { lc.logout(); }
}
如 this answer 中所述,SYSTEM 是一组可以附加到不同帐户的权限。该代码遍历与当前帐户关联的所有主体并测试众所周知的 SYSTEM。
但如果您只对可打印的用户名感兴趣,您可以检查 NTUserPrincipal。
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
String name = System.getProperty("user.name"); // just a fall-back
for(Principal p: subject.getPrincipals()) {
if(p.toString().startsWith("NTUserPrincipal: ")) {
name = p.getName();
break;
}
}
System.out.println("Hello " + name);
}
finally { lc.logout(); }
如果您可以直接依赖 com.sun.security.auth
包(或 Java 9+ 中的 jdk.security.auth
模块),则可以直接使用特定的主体类型
LoginContext lc = new LoginContext(APP_NAME, null, null, CONFIG);
lc.login();
final Subject subject=lc.getSubject();
try {
boolean system = false;
for(NTSidUserPrincipal p: subject.getPrincipals(NTSidUserPrincipal.class)) {
if(p.getName().equals("S-1-5-18")) {
system = true;
break;
}
}
Set<NTUserPrincipal> up = subject.getPrincipals(NTUserPrincipal.class);
String name = up.isEmpty()?
System.getProperty("user.name"): up.iterator().next().getName();
System.out.println("Hello " + name+(system? " *": ""));
}
finally { lc.logout(); }