2010-12-03 14 views

Respuesta

19

Encontré este fragmento de código en línea, creo que hará el trabajo por usted.

public static boolean isAdmin() { 
    String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs(); 
    for (String group : groups) { 
     if (group.equals("S-1-5-32-544")) 
      return true; 
    } 
    return false; 
} 

SÓLO funciona en Windows, y viene integrado en el paquete principal de Java. Acabo de probar este código y funciona. Me sorprendió, pero lo hace.

El SID S-1-5-32-544 es la identificación del grupo Administrador en el sistema operativo Windows.

Here is the link para obtener más información sobre cómo funciona.

+10

S-1-5-32-544, por supuesto, LMFAO: D –

+4

Good ol 'S-1-5-32-544. Debería haber pensado en eso. – Tom

+1

... Y solo con Sun JVM debido a clases privadas. –

5

No existe tal recurso disponible en Java Runtime Environment, pero podría estar en una rutina nativa dependiente de la plataforma. Tenga en cuenta que, por lo general, la mejor manera de estar seguro es tratar de hacerlo, y ver si falla.

3

Solo al intentar una operación que requiera tal acceso (como vincular un puerto de bajo número, o abrir un archivo que se sabe protegido).

+0

Gracias. Eso funcionó para mí. Intenté crear un archivo de prueba en archivos de programa y atrapé IOException (Acceso denegado) ... nuevo archivo (System.getenv ("programfiles") + "/ test.tst"). CreateNewFile() –

+0

¡Sólo Windows, por supuesto! –

0

O usted podría hacer esto:

System.getenv().get("USER")

Y ver qué usuario inició el proceso.

Cuando lo ejecuto como yo obtengo "goran", cuando lo ejecuto con sudo obtengo "root". Funciona en Linux. Probablemente lo que se necesitaba.

+0

Hmm, esto es interesante, déjame probar esto y ver qué hace en Windows. Si dice "admin", esto funcionará. – user489041

+1

Y, por favor, publique sus resultados. Realmente me gustaría saber si esto es independiente del sistema operativo –

+0

En Windows 7, obtengo un valor nulo si ejecuto este código. Sin embargo, si ejecuto System.getProperty ("nombre.usuario"), obtengo mi nombre de usuario. Pero, esto todavía no dice si soy administrador o no. – Codemwnci

2

El método de la respuesta marcada mejor funcionó bien para mí hasta el momento en que tuve que construir el código en Jenkins en una máquina Linux. com.sun.security.auth.module.NTSystem() no está disponible allí y el uso de paquetes de sol generalmente se considera una mala práctica: link

+0

Tome la "rt.jar" de su máquina de Windows. Agréguelo a la ruta de clase en su máquina Linux. Luego, tenga un código dentro de su aplicación que pueda ver si es una PC con Windows, ejecute la respuesta aceptada, si es Linux, ejecute las respuestas de Linux a partir de esta pregunta. La primera solución que viene a la mente. Para mí, solo necesitaba hacer esto en Windows, así que no tuve este problema. Es una de esas cosas en las que Java es una mierda. Solo una nota al margen, debe agregar esto como un comentario. – user489041

+0

¡Gracias por la pista sobre el rt.jar! Voy a darle una oportunidad. PD: Sé que esto debería haber sido un comentario, pero desafortunadamente, debido a la forma algo extraña de stackoverflow otorga permisos, con mi reputación actual solo puedo comentar mis propias respuestas/preguntas =) –

25

He encontrado una solución diferente que parece ser independiente de la plataforma. Intenta escribir preferencias del sistema. Si eso falla, el usuario podría no ser un administrador.

public static boolean isAdmin(){ 
    Preferences prefs = Preferences.systemRoot(); 
    try{ 
     prefs.put("foo", "bar"); // SecurityException on Windows 
     prefs.remove("foo"); 
     prefs.flush(); // BackingStoreException on Linux 
     return true; 
    }catch(Exception e){ 
     return false; 
    } 
} 

Como Tomáš Zato sugerido, es posible que desee suprimir mensajes de error causados ​​por este método. Puede hacerlo configurando System.err:

public static boolean isAdmin(){ 
    Preferences prefs = Preferences.systemRoot(); 
    PrintStream systemErr = System.err; 
    synchronized(systemErr){ // better synchroize to avoid problems with other threads that access System.err 
     System.setErr(null); 
     try{ 
      prefs.put("foo", "bar"); // SecurityException on Windows 
      prefs.remove("foo"); 
      prefs.flush(); // BackingStoreException on Linux 
      return true; 
     }catch(Exception e){ 
      return false; 
     }finally{ 
      System.setErr(systemErr); 
     } 
    } 
} 
+1

Bueno, pero sugiero que almacena en caché el estado en una variable estática privada. No va a cambiar dentro de una instancia del programa. –

+0

@ TomášZato Definitivamente tienes razón en que no va a cambiar, pero quería que el ejemplo de código fuera lo más corto posible – MyPasswordIsLasercats

+1

Una cosa más: la función sigue generando resultados, como 'Kvě 07, 2015 1:49: 14 ODP. java.util.prefs.WindowsPreferences ADVERTENCIA: No se pudo abrir/crear el nodo raíz de preferencias Software \ JavaSoft \ Prefs en la raíz 0x80000002. Windows RegCreateKeyEx (...) devolvió el código de error 5.' ¿Es posible suprimir estos? –

Cuestiones relacionadas