Before you install the plugin, ensure that software requirements are met for proper installation of the plugin.
NOTE: Opening any item from File->New->Other…->ThingWorx will also change the perspective to ThingWorx Extension.
You are ready to start a ThingWorx Extension Project!
In this tutorial, you will create a ThingWorx extension that performs authentication based on your security needs.
The information from ThingWorx Extension Properties is used to populate the metadata.xml file in your project. The metadata.xml file contains information about the extension and details for the various artifacts within the extension. The information in this file is used in the import process in ThingWorx to create and initialize the entities.
You will be able to check these settings within the metadata.xml file inside of the configfiles directory.
You will now need to add the stubs for the authenticate, issueAuthenticationChallenge, and matchesAuthRequest methods. See below for sample code and descriptions.
Method | Description |
Constructor | Needed to instantiate new objects of type AwesomeCustomAuthenticator. Instance member data/variable values in your Authenticator will not be available across requests. |
initializeEntity | This method is called when the Authenticator Thing is saved in ThingWorx Composer, e.g. saving configuration table updates. |
authenticate | The logic/implementation that is used to authenticate a HTTP request. |
issueAuthenticationChallenge | Handles logic which follows authentication failure (e.g. logging an error). |
matchesAuthRequest | This method determines if this Authenticator is valid for the authentication request type. |
Below provides more information about each of these methods and some example source code:
@Override public void authenticate(HttpServletRequest request, HttpServletResponse response) throws AuthenticatorException { String username = request.getHeader("User"), password = request.getHeader("Password"); if(username.isEmpty() || password.isEmpty()) throw new AuthenticatorException("User login info is empty"); try { // This section logs the latest login time and login user to a thing called MyThing // Subscribing to these properties via DataChange event will allow this information to be stored Thing LoginHelper = (Thing) EntityUtilities.findEntity("MyThing", ThingworxRelationshipTypes.Thing); LoginHelper.setPropertyValue("LatestLoginUser", new StringPrimitive(username)); LoginHelper.setPropertyValue("LatestLoginTime", new DatetimePrimitive(DateTime.now())); _logger.warn(DateTime.now() + " -- " + username + " login attempt"); // Checks that user exists and is enabled; throws exception if can't validate // May want to create user in ThingWorx if they don't exist AuthenticationUtilities.validateEnabledThingworxUser(username); // Checks that user exists and validates credentials through all configured DirectoryServices // (one is the internal directory of ThingWorx users, one could be LDAP if configured); // throws exception if can't validate AuthenticationUtilities.validateCredentials(username, password); // REQUIRED: tells rest of ThingWorx which user is logged in for purposes of permissions, etc. this.setCredentials(username); } }
Example code below. This sample code for Authenticator to automatically login the user with default username/password when specific URI used in web browser.
@Override public boolean matchesAuthRequest(HttpServletRequest httpRequest) throws AuthenticatorException { String requestURI = httpRequest.getRequestURI(); // Must access it from this URL and not from /Thingworx/Runtime/index.html#mashup=LogoutButtonMashup as // the Request URI in the latter case is always going to show as /Thingworx/Runtime/index.html if (requestURI.equals("/Thingworx/Mashups/LogoutButtonMashup")) return true; else return false; }
Below is another example of how to implement the matchesAuthRequest method. Of course, it’s not a safe method. Nevertheless, it provides input into a different way to handle things.
@Override public boolean matchesAuthRequest(HttpServletRequest request) throws AuthenticatorException { try { // DON'T DO THIS by itself -- getHeader returns null if it can't find the header, // so this is unsafe and may block other authenticators from attempting String value1 = request.getHeader("User"); String value2 = request.getHeader("Password"); // DO ADD THIS - this is safe // Optionally add some logging statement here to inform of missing headers if(value1 == null || value2 == null) return false; return true; } catch(Exception e) { // This won't normally hit. This is really for other, more complicated validation processes throw new AuthenticatorException("Missing headers"); } }
You can use either Gradle or Ant to build your ThingWorx Extension Project.
build: [echo] Building AuthenticatorExample extension package... BUILD SUCCESSFUL Total time: 770 milliseconds