How to use NetLicensing with Java and Spring Security

Recently we started a journey through user Authentication-Authorization and entitlements Validation process with the article What is Authentication-Authorization-Validation Framework.

Now that we have a basic understanding of AAV Framework and what it brings to us, I think it’s time to see how we can apply this to enhance user authorization flow.


We will use Spring Security demo project as a good starting point. This demo project offers implementation of sample authentication and authorization process as well as simple UI (Spring MVC Framework).

These steps needed to integrate NetLicensing customer entitlements validation in the Java Spring Security project:

  • Setup Spring Security Project
  • Configure NetLicensing Product
  • Integrate NetLicensing RESTful API

Setup Spring Security Project

Prerequisites

  • Installed Java (>= 8.x)
  • Installed Maven (>= 3.5)

Spring Security demo project can be cloned or forked on GitHub.

> git clone https://github.com/Labs64/gs-securing-web

After clone, you can verify your setup and preconditions by executing:

> cd complete
> ./mvnw spring-boot:run

First execution might take a bit more time, as all needed Maven project dependencies need to be downloaded in your local Maven repository.

If everything works well, you should see the following message:

...
2020-11-13 10:04:43.948  INFO 5093 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
...

… and you can open the website in your browser at localhost:8080 (make sure you are using Tomcat port number from the log message).

To work with the java source code, you can use any available IDE; e.g. Eclipse, IntelliJ IDEA, VSCode, etc.

So, now your development environment is set up, and we can move on to the next step.

Configure NetLicensing Product

As next, we will create NetLicensing product configuration, which will be used to specify customers entitlements. You can create the product, module and packages configurations manually (you might find these video tutorials helpful) or simply open Demo Data view and create one of the demo configurations for the chosen Licensing Model.

After this step is finished, you should have the following entities created:

Product

NetLicensing Product corresponds to your specific product being offered to the end-customers.

NetLicensing Product

For this demo, we recommend enabling “Auto-create customer” option, so every not-existing customer will be created automatically upon the first validation request.

Module

NetLicensing Module represents a specific product licensing schema and configured using one of the supported Licensing Models.

NetLicensing Module

Did you know!

One product in the NetLicensing can be configured using more than one licensing models, which is allowing you the highest level of customization accordingly to your business needs.

Packages

NetLicensing Package is an individual product module configuration which is defining licensing packages offered to the end-customers.

NetLicensing Packages

Did you know!

Modules & Packages configuration can vary depending on the chosen licensing model.

You need to note the following configuration data for the NetLicensing API integration described in the next chapter:

  • Product Number
  • Module Number

Integrate NetLicensing RESTful API

NetLicensing offers a very flexible RESTful API, which can be implemented with almost every programming language and technology stack. To speed up integration, a set of predefined client libraries is provided. In this demo, we will be using NetLicensing Java Client library.

Maven dependency

NetLicensing Java Client library needs to be added as a project dependency in the pom.xml file

complete/pom.xml

<dependency>
  <groupId>com.labs64.netlicensing</groupId>
  <artifactId>netlicensing-client</artifactId>
  <version>2.5.8</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>jul-to-slf4j</artifactId>
    </exclusion>
  </exclusions>
</dependency>

For this demo, we will slightly modify Spring Security configuration and allow every username with the same password as username (e.g. guidechimp:guidechimp)

complete/src/main/java/com/example/securingweb/WebSecurityConfig.java

@Override
protected void configure(HttpSecurity http) throws Exception {
	http.authorizeRequests().antMatchers("/", "/home").permitAll().anyRequest().authenticated().and().formLogin()
			.loginPage("/login").permitAll().and().logout().permitAll();
}

@Bean
@Override
public UserDetailsService userDetailsService() {
	return new UserDetailsService() {

		@Override
		public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
			// Set password same as username
			return User.withDefaultPasswordEncoder().username(username).password(username).roles("USER").build();
		}

	};
}

Every logged-in user will be forwarded to the /hello page. We introduced a new controller class, which will receive username for the logged-in user and use this to validate users entitlements in the NetLicensing.

This class need to be changed with the specific configuration you made in the previous step:

  • NLIC_APIKEY - NetLicensing API Key with the Role: Licensee; API Key can be created in the Management Console / Settings view.
  • NLC_PRODUCT - use created Product Number
  • NLC_MODULE - use created Module Number

After successful validation, the result will be added to the Spring MVC model object and shown on the /hello page.

complete/src/main/java/com/example/securingweb/NetLicensingController.java

@GetMapping("/hello")
public String greeting(Model model) throws NetLicensingException {

    // NetLicensing configuration
    // API Key - min role needed: Licensee
    final String NLIC_APIKEY = "ea624604-028e-458c-b5e5-85bc6620b890";
    // Product number
    final String NLC_PRODUCT = "P1S85TDRU-DEMO";
    // Product module number
    final String NLC_MODULE = "MTGTOW8EC-DEMO";

    // Initiate NetLicensing context
    final Context context = new Context();
    context.setBaseUrl("https://go.netlicensing.io/core/v2/rest");
    context.setSecurityMode(SecurityMode.APIKEY_IDENTIFICATION);
    context.setApiKey(NLIC_APIKEY);

    // Prepare validation request
    final ValidationParameters validationParameters = new ValidationParameters();
    validationParameters.setProductNumber(NLC_PRODUCT);
    // Send validation request; where current login username will be used as unique customer identifier
    ValidationResult validationResult = LicenseeService.validate(context, getUsername(), validationParameters);

    // Prepare model to be rendered on the hello page
    Composition moduleValidation = validationResult.getProductModuleValidation(NLC_MODULE);
    model.addAttribute("name", getUsername());
    model.addAttribute("moduleValidation", moduleValidation);

    return "hello";
}

Hello page was extended in order to show NetLicensing validation status and other relevant information.

complete/src/main/resources/templates/hello.html

...
<hr>
<h2 th:inline="text">[[${moduleValidation.properties.get('productModuleName')}]]!</h2>
<p th:text="'- valid: ' + ${moduleValidation.properties['valid']}" />
<p th:text="'- expires: ' + ${moduleValidation.properties['expires']}" />
<p th:text="'RAW validation result: ' + ${moduleValidation}" />
...

Now you can start the project again and verify NetLicensing integration.

> ./mvnw spring-boot:run

Conclusion

With the above simple adjustments, we added the possibility to validate customers licenses maintained in the NetLicensing system.

This validation process extends standard authentication & authorization steps and allows you to drive application behaviour based on the customer’s entitlements and validation status.


We are always happy to receive your feedback as well as suggestions on how we can improve NetLicensing services. Get in touch with us here.

Source code: Labs64/gs-securing-web

Image Credits: NetLicensing