Other strategies for authentication and authorization
There are cases in which you want to exercise great control over who is allowed to use your application. You might, for example, be required to check the user’s network credentials, validate client-side certificate or check a license server before the platform application is even launched.
It is important to note that because the platform has not been initialized at this point, none of the usual platform capabilities will be available. If you simply want to enable a single module based on some criteria (for example, the existence of a license file), you can use ModuleInstall.validate().
A platform application is typically started from an executable launcher (Windows) or shell script (Unix).
This invokes the org.netbeans.core.startup.Main.main
method.
However, as described in the Module System documentation, you can use the netbeans.mainclass
system property to specify a different class to run at startup.
This class should exist in a JAR file in the startup classpath (you can put it alongside core.jar
in the platform/core
directory). This class must also have a main method which can invoke whatever authorization logic you like. If authorization fails, you’ll probably want to show a dialog and call System.exit
. If it succeeds, you can invoke the org.netbeans.core.startup.Main
class' main
method yourself to continue the normal NetBeans startup procedure. But because org.netbeans.core.startup.Main
is not a public API, you will need to invoke it indirectly using reflection. Here is an example of a custom startup class that does this:
package com.tomwheeler;
import java.lang.reflect.Method;
public class CustomStartup {
private static final String NB_MAIN_CLASS = "org.netbeans.core.startup.Main";
public static void main(String[] args) throws Exception {
// do whatever you need here (e.g. show a custom login form)
System.out.println("Hello world! I am a custom startup class");
// once you're done with that, hand control back to NetBeans
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Class<?> mainClass = Class.forName(NB_MAIN_CLASS, true, classloader);
Object mainObject = mainClass.newInstance();
Method mainMethod = mainClass.getDeclaredMethod("main", new Class[]{String[].class});
mainMethod.invoke(mainObject, (Object) args);
}
}
The easiest thing to do is create a Java Class Library project (not a module project) in the NetBeans IDE, create a class like the one above and then build the project to create a JAR file. Copy that JAR file to the platform/core
directory of your platform and then start your application using the following command line:
myapp.exe -J-Dnetbeans.mainclass=com.tomwheeler.CustomStartup
You will probably want to put this system property in the application’s configuration file (where you’d add JVM memory flags) so it will be permanent.
Clever users could work around this by editing the command line and bypassing the restriction, so the security of this approach is limited by itself. If this is a concern, you may overcome it by having your custom main class encrypt a flag value (which perhaps contains a nonce/timestamp to prevent replay attacks) and passing it (e.g. as a system property) to your platform application which will then decrypt and verify it. Thus, the logic for validating the user is entirely in the custom main class (or the code which it invokes), while the platform application need only verify that this step has actually been performed.