【问题标题】:How to determine if account running java application is 'SYSTEM'如何确定运行 java 应用程序的帐户是否为“SYSTEM”
【发布时间】:2020-11-30 14:36:33
【问题描述】:

如何检查我的 Java 应用程序是否作为“系统”/“本地系统”运行(如 Windows 服务列表中所示)?

我试过用这个:

System.out.println("Running with user: " + System.getenv().get("USERDOMAIN") + "\\" + System.getenv().get("USERNAME"));

...但它似乎根据程序运行的位置返回DOMAIN\COMPUTERNAME。所以它可以像 DOMAIN1\COMPUTER1 和其他地方是 FOO\SERVER451 并且都仍然意味着“SYSTEM”帐户。

关于背景信息,我的 Java 应用程序使用“Apache Commons Daemon Service Runner”包装到 Windows 服务中,默认情况下它将作为“本地系统”运行(与示例图像中的方式相同)。

我真的很想简化我的代码以打印SYSTEMMYDOMAIN\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 2002 年 12 月 20 日: 从超级用户的这个帖子中找到了一些关于 SYSTEM 帐户的好信息:https://superuser.com/questions/265216/windows-account-ending-with

【问题讨论】:

  • 假设您确实从程序中确定它是否作为系统运行。您希望如何处理这些信息?你真正想解决什么问题?
  • @KarlKnechtel 我不会说我有“问题”,但这对于安装了多个“代理”(Java 应用程序)的应用程序来说是一个改进,我想从中收集统计信息以 SYSTEM 身份运行,哪些不是。

标签: java java-8 local-system-account


【解决方案1】:

这是目前为止我能想到的最好的了

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多