JASYPT Password Encryption with Spring MVC REST API and MongoDB Example

JASYPT Password Encryption with Spring MVC REST API and MongoDB Example

In this tutorial we will discuss how to use Java Simplified Encryption (JASYPT) for encrypting and decrypting our MongoDB password contained in our properties files. This allows us to replace any clear text passwords in our property and XML files. These are decrypted at runtime by JASYPT using our secured key. This JASYPT java example will focus on converting our clear text passwords to encrypted ones and storing them in our *.properties files which are read by our classes when our Spring MVC application is first started.

JASYPT Java Password Encryption and Decryption

What’s Covered

  1. Getting Started
  2. Creating user with Role-Based Authentication in MongoDB
  3. Start up MongoDB (Standard Mode)
  4. Start the MongoDB Shell
  5. Setting Up Web User in MongoDB
  6. Start up MongoDB (Authentication Mode)
  7. Testing Auth Mode with MongoDB Shell
  8. JASYPT Command-Line Interface
  9. Encrypting our Password using the JASYPT CLI
  10. Decrypting our Password using the JASYPT CLI
  11. Modify Tomcat catalina.bat File
  12. Defining the Environment on Tomcat Servers
  13. The MongoConfiguration
  14. TomcatEnvironment Class
  15. The Person Model
  16. Our Controller Class (RestController.java)
  17. PersonRepository Data Access Object (DAO) for MongoDB
  18. Web Deployment Descriptor
  19. Configure Spring Web DispatcherServlet
  20. Testing out Jasypt with our Web Services

Getting Started

In order to run this tutorial yourself, you will need the following:

  • Java JDK 1.6 or greater
  • Favorite IDE Spring Tool Suite (STS), Eclipse IDE or NetBeans (I happen to be using STS because it comes with a Tomcat server built-in)
  • Tomcat 7 or greater or other popular container (Weblogic, Websphere, Glassfish, JBoss, VMWare vFabric, etc). For this tutorial I am using VMware vFabric tc Server Developer Edition which is essentially an enhanced Tomcat instance integrated with Spring STS
  • JASYPT is a java library which allows the developer to add basic encryption capabilities to projects with minimum effort.
  • MongoDB is an open-source document database designed for ease of development and scaling.
  • Jackson Mapper for Object to JSON and vice-versa serialization/deserialization
  • Logback (for logging purposes)

Required Libraries

Copy all of the following jars to WebContent->WEB-INF->lib folder.

aopalliance-1.0.jar
aspectjrt-1.6.10.jar
commons-logging-1.2.jar
jackson-core-asl-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
jasypt-1.9.2.jar
logback-access-1.1.3.jar
logback-classic-1.1.3.jar
logback-core-1.1.3.jar
mongo-java-driver-3.2.0.jar
slf4j-api-1.7.12.jar
spring-aop-4.0.6.RELEASE.jar
spring-aspects-4.0.6.RELEASE.jar
spring-beans-4.0.6.RELEASE.jar
spring-context-4.0.6.RELEASE.jar
spring-core-4.0.6.RELEASE.jar
spring-data-commons-1.11.0.RELEASE.jar
spring-data-mongodb-1.8.2.RELEASE.jar
spring-data-mongodb-1.8.6.RELEASE.jar
spring-expression-4.0.6.RELEASE.jar
spring-test-4.0.6.RELEASE.jar
spring-tx-4.0.6.RELEASE.jar
spring-web-4.0.6.RELEASE.jar
spring-webmvc-4.0.6.RELEASE.jar

Complete Project Overview

I have added the project overview to give you a full view of the structure and show you all files contained in this sample project.

jasypt_security_proj_struct

RESTful Web Service End Points

#URIMethodDescription
1/rest/statusGETDisplays the standard status message.
2/rest/personsGETRetrieves all person objects from MongoDB returning them as a JSON array.
3/rest/getPersonByIdGETRetrieves an person given the ID, returning the person as JSON object.
4/rest/getByFirstNameGETRetrieves an person given the First Name, returning the person as JSON object.
5/rest/getByLastNameGETRetrieves an person given the Last Name, returning the person as JSON object.

Creating user with Role-Based Authentication in MongoDB

In this tutorial we will be creating a user called webuser and assign them a role called readWrite to the database called datastore.

Start up MongoDB (Standard Mode)

Let’s change directory to the directory containing the mongoDB bin folder. In our case, this directory resides in C:\Program Files\MongoDB\Server\3.2\bin. We start the mongoDB process by running mongod.

C:\>cd Program Files\MongoDB\Server\3.2\bin
C:\Program Files\MongoDB\Server\3.2\bin>mongod
[initandlisten] MongoDB starting : pid=14184 port=27017 
                dbpath=C:\data\db\ 64-bit host=AMAURYPC
[initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
[initandlisten] db version v3.2.0
[initandlisten] git version: 45d947729a0315accb6d4f15a6b06be6d9c19fe7
[initandlisten] OpenSSL version: OpenSSL 1.0.1p-fips 9 Jul 2015
[initandlisten] allocator: tcmalloc
[initandlisten] modules: none
[initandlisten] build environment:
[initandlisten]     distmod: 2008plus-ssl
[initandlisten]     distarch: x86_64
[initandlisten]     target_arch: x86_64
[initandlisten] options: {}
[initandlisten] Detected data files in C:\data\db\ created by the 
                'mmapv1' storage engine, so setting the active storage 
                engine to 'mmapv1'.
[initandlisten] journal dir=C:\data\db\journal
[initandlisten] recover : no journal files present, no recovery needed
[durability] Durability thread started
[journal writer] Journal writer thread started
[HostnameCanonicalizationWorker] Starting hostname canonicalization
[initandlisten] Initializing full-time diagnostic data capture with 
                directory 'C:/data/db/diagnostic.data'
[initandlisten] waiting for connections on port 27017

Start the MongoDB Shell

Once we have MongoDB running on our PC or server we will need to start the mongoDB shell. We do this by running the mongo executable in the same directory where mongod resides which, in our case, is C:\Program Files\MongoDB\Server\3.2\bin.

C:\Program Files\MongoDB\Server\3.2\bin>mongo
MongoDB shell version: 3.2.0
connecting to: test
> 

Setting Up Web User in MongoDB

Now that we are running the MongoDB shell, it’s time to create the user webuser we need for this tutorial and assigns the appropriate password, role and database. We will use the db.createUser() shell command.

use <database>
 db.createUser({JSON})
 db.<collection>.print()
> use datastore
switched to db datastore
> db.createUser({ 
  user: "webuser", 
  pwd: "Mapl38yrup", 
  roles: [ { 
           role: "readWrite", 
           db: "datastore" 
         }]
  })
>
Successfully added user: {
   "user" : "webuser",
   "roles" : [
      {
         "role" : "readWrite",
         "db" : "datastore"
      }
   ]
}

Start up MongoDB (Authentication Mode)

Once the user has been created, we must stop the current instance of MongoDB (mongod). In Windows you can hit Ctrl + C in the command prompt running MongoDB.

This time we will start the MongoDB process by running mongod –auth in order to enable MongoDB Auth mode. Once we have enabled authentication, all users will be required to identify themselves and pass MongoDB the user’s credentials.

C:\>cd Program Files\MongoDB\Server\3.2\bin
C:\Program Files\MongoDB\Server\3.2\bin>mongod --auth
[initandlisten] MongoDB starting : pid=6596 port=27017 
                dbpath=C:\data\db\ 64-bit host=AMAURYPC
[initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
[initandlisten] db version v3.2.0
[initandlisten] git version: 45d947729a0315accb6d4f15a6b06be6d9c19fe7
[initandlisten] OpenSSL version: OpenSSL 1.0.1p-fips 9 Jul 2015
[initandlisten] allocator: tcmalloc
[initandlisten] modules: none
[initandlisten] build environment:
[initandlisten]     distmod: 2008plus-ssl
[initandlisten]     distarch: x86_64
[initandlisten]     target_arch: x86_64
[initandlisten] options: { security: { authorization: "enabled" } }
[initandlisten] Detected data files in C:\data\db\ created by the 
                'mmapv1' storage engine, so setting the active storage 
                engine to 'mmapv1'.
[initandlisten] journal dir=C:\data\db\journal
[initandlisten] recover : no journal files present, no recovery needed
[durability] Durability thread started
[journal writer] Journal writer thread started
[HostnameCanonicalizationWorker] Starting hostname canonicalization
[initandlisten] Initializing full-time diagnostic data capture with 
                directory 'C:/data/db/diagnostic.data'
[initandlisten] waiting for connections on port 27017

Testing Auth Mode with MongoDB Shell

At this point, let’s start a new session of MongoDB shell and pass in the username, password and the authentication database to ensure that it works as intended. We will then connect to the datastore database and print out all of the documents in the Person collection using the db.Person.find().

mongo --port 27017 -u "webuser" -p "Mapl38yrup" 
                       --authenticationDatabase "datastore"
>
> use datastore
switched to db datastore
> db.Person.find()
{ "_id" : ObjectId("57f1a03d520011c322baab7c"), 
"firstName" : "Amaury", "lastName" : "Valdes", 
"address" : "100 Main Street", "city" : "Morris Plains", 
"state" : "New Jersey", "zipCode" : "08837" }
{ "_id" : ObjectId("57f1a072520011c322baab7d"), 
"firstName" : "Nancy", "lastName" : "Smith", "address" 
: "12 Green Street", "city" : "Austin", "state" : 
"New Jersey", "zipCode" : "01923" }
{ "_id" : ObjectId("57f1a800520011c322baab7e"), 
"firstName" : "Jerry", "lastName" : "Riser", 
"address" : "928 Maple Road", "city" : "Somerville", 
"state" : "New Jersey", "zipCode" : "07076" }

JASYPT Command-Line Interface

JASYPT supplies a bunch of Command Line Interface (CLI) tools, useful for performing encryption, decryption and digest operations from the command line. For the sake of this tutorial, I have included the CLI tools in a directory called cliTools and the two necessary jar files in a directory called lib.

In order to use this tools, you should download the distribution zip file.

We will use this CLI tools to encrypt our input string using the password of our choosing. We will then take the output of encryption and use it in our *.properties files. The only caveat is that we must enclose the encrypted string inside of ENC ( ) tag.

Encrypting our Password using the JASYPT CLI

encrypt input=<input_string> password=<password>
>encrypt input=Mapl38yrup password=MyS3cr3t!

----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.79-b02

----ARGUMENTS-------------------
input: Mapl38yrup
password: MyS3cr3t!

----OUTPUT----------------------
ag7xtRuF67pIIFbAUdqf4riTiajqliBr

Decrypting our Password using the JASYPT CLI

decrypt input=<encrypted_string> password=<password>
>decrypt input=ag7xtRuF67pIIFbAUdqf4riTiajqliBr password=MyS3cr3t!

----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.79-b02

----ARGUMENTS-------------------
input: ag7xtRuF67pIIFbAUdqf4riTiajqliBr
password: MyS3cr3t!

----OUTPUT----------------------
Mapl38yrup

Default Property File (jasyptSecurityExample.default.properties)

Please note, in order to keep simplify things, all environments are using the same username/password combination. In a true PROD environment this is usually not the case.

property.name=default

#---MongoDB Objects Setup---
mongo.hostname=localhost
mongo.port=27017
mongo.username=webuser
mongo.password=ENC(ag7xtRuF67pIIFbAUdqf4riTiajqliBr)
mongo.dbName=datastore
mongo.auth_mechanism=SCRAM-SHA-1
mongo.auth_source=datastore

DEV Property File (jasyptSecurityExample.dev.properties)

property.name=dev

#---MongoDB Objects Setup---
mongo.hostname=dev.avaldes.com
mongo.port=27017
mongo.username=webuser
mongo.password=ENC(ag7xtRuF67pIIFbAUdqf4riTiajqliBr)
mongo.dbName=datastore
mongo.auth_mechanism=SCRAM-SHA-1
mongo.auth_source=datastore

UAT Property File (jasyptSecurityExample.uat.properties)

property.name=uat

#---MongoDB Objects Setup---
mongo.hostname=uat.avaldes.com
mongo.port=27017
mongo.username=webuser
mongo.password=ENC(ag7xtRuF67pIIFbAUdqf4riTiajqliBr)
mongo.dbName=datastore
mongo.auth_mechanism=SCRAM-SHA-1
mongo.auth_source=datastore

PROD Property File (jasyptSecurityExample.prod.properties)

property.name=prod

#---MongoDB Objects Setup---
mongo.hostname=prod.avaldes.com
mongo.port=27017
mongo.username=webuser
mongo.password=ENC(ag7xtRuF67pIIFbAUdqf4riTiajqliBr)
mongo.dbName=datastore
mongo.auth_mechanism=SCRAM-SHA-1
mongo.auth_source=datastore

Modify Tomcat catalina.bat File

For this procedure to work we will need to modify the catalina.bat or catalina.sh shell script. We will need to add an ENVIRONMENT variable to the tomcat startup script and define it as one of the three dev, uat and prod environments. Our TomcatEnvironment class will then read ENVIRONMENT variable and based on on the value, it will use the appropriate
jasyptSecurityExample.XXXX.properties property file.

You will notice that I include one additional property file called default. This is used for our local development environment when we don’t want to set up or are unable to set up an ENVIRONEMNT variable. This is open the case when working in our favorite IDE (Integrated Development Environment). When our TomcatEnvironment class is not able to find the ENVIRONMENT variable it will default to using the jasyptSecurityExample.default.properties property file.

catalina.bat File Snippet

...
:noJuliManager
set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%"

set "JAVA_OPTS=%JAVA_OPTS% -DENVIRONMENT=dev"
rem ----- Execute The Requested Command -------

echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"
if ""%1"" == ""debug"" goto use_jdk
echo Using JRE_HOME:        "%JRE_HOME%"
goto java_dir_displayed
:use_jdk
echo Using JAVA_HOME:       "%JAVA_HOME%"
:java_dir_displayed
echo Using CLASSPATH:       "%CLASSPATH%"
...

catalina.sh File Snippet

...
# org.apache.catalina.security.SecurityListener
JAVA_OPTS="$JAVA_OPTS -DENVIRONMENT=dev"
# ----- Execute The Requested Command ---------
# Bugzilla 37848: only output this if we have a TTY
if [ $have_tty -eq 1 ]; then
  echo "Using CATALINA_BASE:   $CATALINA_BASE"
  echo "Using CATALINA_HOME:   $CATALINA_HOME"
  echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"
...

Defining the Environment on Tomcat Servers

tomcat_environment_setup

MongoConfiguration Output

Once the application is started and our TomcatEnvironment

2016-10-06 10:42:19.690 INFO  com.avaldes.util.TomcatEnvironment 
- Trying to get environment variable from Tomcat Server...
2016-10-06 10:42:19.710 INFO  com.avaldes.util.TomcatEnvironment 
- Environment entry is : dev
2016-10-06 10:42:19.710 INFO  com.avaldes.util.TomcatEnvironment 
- properties_filename is : jasyptSecurityExample.dev.properties
2016-10-06 10:42:19.710 INFO  com.avaldes.util.TomcatEnvironment 
- Trying to read property filename from: 
jasyptSecurityExample.dev.properties

2016-10-06 10:42:19.753 INFO  com.avaldes.util.MongoConfiguration 
- Inside jasyptMongoDbFactory()...
2016-10-06 10:42:19.833 INFO  com.avaldes.util.MongoConfiguration 
- Mongo Configuration URI: mongodb://webuser:Mapl38yrup@localhost:27017/
datastore?authMechanism=SCRAM-SHA-1&authSource=datastore
2016-10-06 10:42:19.833 INFO  com.avaldes.util.MongoConfiguration 
-    hostname............: [localhost]
2016-10-06 10:42:19.835 INFO  com.avaldes.util.MongoConfiguration 
-    port................: [27017]
2016-10-06 10:42:19.835 INFO  com.avaldes.util.MongoConfiguration 
-    username............: [webuser]
2016-10-06 10:42:19.836 INFO  com.avaldes.util.MongoConfiguration 
-    password............: [*******]
2016-10-06 10:42:19.837 INFO  com.avaldes.util.MongoConfiguration 
-    database............: [datastore]
2016-10-06 10:42:19.837 INFO  com.avaldes.util.MongoConfiguration 
-    auth_source.........: [datastore]
2016-10-06 10:42:19.838 INFO  com.avaldes.util.MongoConfiguration 
-    auth_mechanism......: [SCRAM-SHA-1]
2016-10-06 10:42:20.064 INFO  org.mongodb.driver.cluster 
- Cluster created with settings {hosts=[localhost:27017], 
mode=SINGLE, requiredClusterType=UNKNOWN, 
serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2016-10-06 10:42:20.284 INFO  org.mongodb.driver.connection 
- Opened connection [connectionId{localValue:1, serverValue:138}] 
to localhost:27017

The MongoConfiguration Class (MongoConfiguration.java)

package com.avaldes.util;

import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

/**
 * A configuration class to configure Mongo DB Template 
 * and read values from the environment specific 
 * property files.
 *
 */
@Configuration
public class MongoConfiguration {
 private static final Logger logger
                = LoggerFactory.getLogger(MongoConfiguration.class);

 private Properties appProp;
 private static String hostname;
 private static String port;
 private static String username;
 private static String password;
 private static String database;
 private static String auth_mechanism;
 private static String auth_source;
 
 @Bean(name="jasyptMongoDbFactory")
 public MongoDbFactory jasyptMongoDbFactory() 
                             throws UnknownHostException {

  logger.info("Inside jasyptMongoDbFactory()...");
   
  appProp = TomcatEnvironment.getApplicationProperties();
  hostname = appProp.getProperty("mongo.hostname").trim();
  port = appProp.getProperty("mongo.port").trim();  
  database = appProp.getProperty("mongo.dbName").trim();
  username = appProp.getProperty("mongo.username").trim();
  password = appProp.getProperty("mongo.password").trim();
  auth_source = appProp.getProperty("mongo.auth_source").trim();
  auth_mechanism = appProp.getProperty("mongo.auth_mechanism").trim();
  
  String dbURI = String.format("mongodb://%s:%s@%s:%s/
    %s?authMechanism=%s&authSource=%s", username, password, hostname, 
    port, database, auth_mechanism, auth_source);
  
  logger.info("Mongo Configuration URI: " + dbURI);
  logger.info("   hostname............: [" + hostname + "]");
  logger.info("   port................: [" + port + "]");
  logger.info("   username............: [" + username + "]");
  logger.info("   password............: [*******]");
  logger.info("   database............: [" + database + "]");
  logger.info("   auth_source.........: [" + auth_source + "]");
  logger.info("   auth_mechanism......: [" + auth_mechanism + "]");
  
  MongoClient mongoClient = new MongoClient(new MongoClientURI(dbURI));  
  return new SimpleMongoDbFactory(mongoClient, database);    
 }
 
 @Bean(name="jasyptMongoTemplate")
 public MongoTemplate jasyptMongoTemplate() throws Exception {
  logger.info("Inside jasyptMongoTemplate()...");
     return new MongoTemplate(jasyptMongoDbFactory());
 }
}

TomcatEnvironment Class (TomcatEnvironment.java)

package com.avaldes.util;

import java.io.IOException;
import java.util.Properties;

import javax.naming.InitialContext;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class TomcatEnvironment {
 private static final Logger logger 
                  = LoggerFactory.getLogger(TomcatEnvironment.class);
 /***********************************************************
 ** The JASYPT PW_PHRASE MUST BE STORED IN A LOCATION
 ** (PROTECTED FILE, SECURED REST SERVICE, ENVIRONMENT, ETC)
 ** THAT IS NOT EASILY ACCESSIBLE IN PRODUCTION CODE
 ** I HAVE PLACED IN IN THE CODE FOR ILLUSTATION
 ** PURPOSES ONLY....
 ***********************************************************/
 private static final String pw_phrase = "MyS3cr3t!";
 private static Properties applicationProperties = null;
 private static final String filenamePrefix = "jasyptSecurityExample"; 
 private static final String extension = "properties"; 
 private InitialContext initialContext;  
 private static String environment;

 public void init() {
  logger.info("Trying to get environment variable from Tomcat Server");
  
  StandardPBEStringEncryptor encryptor=new StandardPBEStringEncryptor();
  encryptor.setPassword(pw_phrase);
  applicationProperties = new EncryptableProperties(encryptor);

  environment = (String) System.getProperty("ENVIRONMENT");
  logger.info("Environment entry is : " + environment);
  
  if (environment == null) { environment = "default"; }
  String properties_filename = filenamePrefix + "." 
                        + environment + "." + extension;

  logger.info("properties_filename is : " + properties_filename);

  try {
   logger.info("Trying to read property filename from: " 
                                      + properties_filename);
   applicationProperties.load(TomcatEnvironment.class
         .getClassLoader().getResourceAsStream(properties_filename));
  } catch (IOException e) {
   logger.error("Unable to read property filename from: " 
                                      + properties_filename);
   e.printStackTrace();
  }
 }
 
 public static Properties getApplicationProperties() {
  return applicationProperties;
 }

 public InitialContext getInitialContext() {
  return initialContext;
 }

 public void setInitialContext(InitialContext initialContext) {
  this.initialContext = initialContext;
 }

 public static String getEnvironment() {
  return environment;
 }

 public static void setEnvironment(String env) {
  environment = env;
 }

 @Override
 public String toString() {
  return "TomcatEnvironment [initialContext=" + initialContext
    + ", environment=" + environment + "]";
 }
}

The Person Model (Person.java)

The Employee model is used as a basis for storing our Employee object into MongoDB as a document in the collection. This class contains two annotations. The first one, the @Document annotation identifies objects or entities that are going to be persisted to MongoDB. The next one, @Id is used to identify the field that will be used as an ID in MongoDB. This ID is labeled _id in MongoDB.

We will be performing advanced boolean and logical operations via the advanced search tab in our application.

package com.avaldes.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class Person {
 @Id private String id;
 private String firstName;
 private String lastName;
 private String address;
 private String city;
 private String state;
 private String zipCode;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public String getState() {
  return state;
 }

 public void setState(String state) {
  this.state = state;
 }

 public String getZipCode() {
  return zipCode;
 }

 public void setZipCode(String zipCode) {
  this.zipCode = zipCode;
 }

 @Override
 public String toString() {
  return "Person [id=" + id + ", firstName=" + firstName
    + ", lastName=" + lastName + ", address=" + address
    + ", city=" + city + ", state=" + state + ", zipCode="
    + zipCode + "]";
 }
}

Our Controller Class (RestController.java)

Our RestController class is the main class that contains all web service mapping end points defined in our table above. The @Controller annotation indicates that this particular class is playing the role of a controller.

package com.avaldes.tutorial;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.avaldes.dao.PersonRepository;
import com.avaldes.model.Person;

@Controller
public class RestController {
 private static final Logger logger = LoggerFactory
   .getLogger(RestController.class);
 public static final String APPLICATION_JSON = "application/json";
 public static final String APPLICATION_HTML = "text/html";

 @Autowired
 private PersonRepository personRepository;

 @RequestMapping(value = "/status", 
              method = RequestMethod.GET, produces = APPLICATION_HTML)
 public @ResponseBody String status() {
  return "Application running OK.";
 }

 @RequestMapping(value = "/persons", method = RequestMethod.GET)
 public @ResponseBody List<Person> getAllPersons() {
  logger.info("Inside getAllPersons() method...");

  return personRepository.getAllPersons();
 }

 @RequestMapping(value = "/getPersonById", 
              method = RequestMethod.GET, produces = APPLICATION_JSON)
 public @ResponseBody Person getPersonById(
   @RequestParam("id") int id) {
  Person person = personRepository.getPersonById(id);

  if (person != null) {
   logger.info(
     "Inside getPersonById, returned: " + person.toString());
  } else {
   logger.info("Inside getPersonById, ID: " + id + ", NOT FOUND!");
  }

  return person;
 }

 @RequestMapping(value = "/getByFirstName", method = RequestMethod.GET)
 public @ResponseBody List<Person> getByFirstName(
   @RequestParam("firstName") String firstName) {
  logger.info("Inside getByFirstName() method...");

  List<Person> allPersons = personRepository
    .getPersonByFirstName(firstName);

  return allPersons;
 }

 @RequestMapping(value = "/getByLastName", method = RequestMethod.GET)
 public @ResponseBody List<Person> getByLastName(
   @RequestParam("lastName") String lastName) {
  logger.info("Inside getByLastName() method...");

  List<Person> allPersons = personRepository
    .getPersonByLastName(lastName);

  return allPersons;
 }
}

PersonRepository Data Access Object (DAO) for MongoDB (PersonRepository.java)

In this class you will notice two annotations being used. The first one, @Repository indicates that the class PersonRepository fulfills the role of a Data Access Object of a repository. This class will handle all of the persistence of Person objects and database access for us.

The second annotation, @Autowired indicates that MongoTemplate is autowired from the Spring configuration, in this case our dispatcher-servlet.xml file.

package com.avaldes.dao;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import com.avaldes.model.Person;

@Repository
public class PersonRepository {
 private static final Logger logger 
                      = LoggerFactory.getLogger(PersonRepository.class);
  public static final String COLLECTION_NAME = "Person";
  
  @Autowired
  private MongoTemplate mongoTemplate;
  
  public Person getPersonById(int id) {
  logger.info("Inside getPersonById " + id);
  
  return mongoTemplate.findOne(
    Query.query(Criteria.where("id")
              .is(id)), Person.class, COLLECTION_NAME);
  }
  
  public List<Person> getPersonByLastName(String lastName) {
  return mongoTemplate.find(
    Query.query(Criteria.where("lastName")
              .regex(lastName, "i")), Person.class, COLLECTION_NAME);
  }
  
  public List<Person> getPersonByFirstName(String firstName) {
  return mongoTemplate.find(
    Query.query(Criteria.where("firstName")
              .regex(firstName, "i")), Person.class, COLLECTION_NAME);
  }
  
  public List<Person> getAllPersons() {
   logger.info("Inside getAllPersons...");
    return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
  }
}

LogBack Configuration File (logback.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
 
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>
       %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
      </Pattern>
    </layout>
  </appender>
   
  <logger name="com.avaldes.*" level="info"/>
 
  <root level="info">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

Web Deployment Descriptor (web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>JasyptSecurityExample</display-name>

<listener>
  <listener-class>
  ch.qos.logback.classic.selector.servlet.ContextDetachingSCL
  </listener-class>
</listener>
 
 <!-- The context params that are read by ContextLoaderListener  -->
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/root-context.xml</param-value>
 </context-param>
 
 <listener> 
  <listener-class>
  org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>
 
 <servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
</web-app>

Configure Spring Web DispatcherServlet (dispatcher-servlet.xml)

Modify the dispatcher-servlet.xml and add the necessary MongoDB configurations. You will notice that I have added jasyptMongoTemplate which is used for the mongo operations and MongoFactoryBean which creates the mongo instance to our dispatcher-servlet.xml. jasyptMongoTemplate is configured to use the database settings via MongoFactoryBean.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

 <!-- Enables the Spring MVC @Controller programming model -->
 <mvc:annotation-driven />

 <bean id="initialContext" class="javax.naming.InitialContext"/>

 <bean id="tomcatEnvironment" 
       init-method="init" 
       class="com.avaldes.util.TomcatEnvironment">
       
   <property name="initialContext" ref="initialContext" />  
 </bean>
  
 <bean id="jasyptMongoTemplate" 
       class="org.springframework.data.mongodb.core.MongoTemplate" 
       depends-on="tomcatEnvironment">
       
   <constructor-arg name="mongoDbFactory" ref="jasyptMongoDbFactory" />
 </bean>

 <!-- Use this post processor to translate any MongoExceptions -->
 <bean
  class="org.springframework.dao.annotation
          .PersistenceExceptionTranslationPostProcessor" />

 <bean
  class="org.springframework.web.servlet.mvc
            .annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters">
   <list>
    <bean
     class="org.springframework.http.converter
               .json.MappingJacksonHttpMessageConverter" />
   </list>
  </property>
 </bean>

 <context:component-scan base-package="com.avaldes" />
</beans>

MongoDB Person Collection

{
  "firstName" : "Amaury",
  "lastName": "Valdes",
  "address": "100 Main Street",
  "city": "Morris Plains",
  "state": "New Jersey",
  "zipCode": "08837"
}
{
  "firstName" : "Nancy",
  "lastName": "Smith",
  "address": "12 Green Street",
  "city": "Austin",
  "state": "New Jersey",
  "zipCode": "01923"
}
{
  "firstName" : "Jerry",
  "lastName": "Riser",
  "address": "928 Maple Road",
  "city": "Somerville",
  "state": "New Jersey",
  "zipCode": "07076"
}

Testing out Jasypt with our Web Services

Testing out JASYPT Java example consists of ensuring that we were able to successfully connect to MongoDB with our credentials while MongoDB is running in Authentication Mode.

Download the Complete Source Code for JASYPT Java Example

That’s It!

I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

jasypt_spring_security

Related Spring Posts

  • Creating Hello World Application using Spring MVC on Eclipse IDE
    In this tutorial we will go into some detail on how to set up your Eclipse IDE environment so that you can develop Spring MVC projects. In this post, we will create our first Spring MVC project with the all to familiar “Hello World” sample program.
  • Spring MVC Form Handling Example
    The following tutorial will guide you on writing a simple web based application which makes use of forms using Spring Web MVC framework. With this web application you will be able to interact with the customer entry form and enter all of the required values and submit them to the backend processes. I have taken the liberty of using CSS to beautify and transform the HTML page from a standard drab look and feel to a more appealing view.
  • Spring @RequestHeader Annotation Example
    In this tutorial, we will discuss the different ways that Spring MVC allow us to access HTTP headers using annotation. We will discuss how to access individual header fields from the request object as well accessing all the headers by supplying Map and then iterating through the LinkedHashMap collection. We will also show you how to set the headers in the response object.
  • Spring MVC Exception Handling using @ExceptionHandler with AngularJS GUI
    Good exception handling is a essential part of any well developed Application Framework and Spring MVC is no exception — pardon the pun. Spring MVC provides several different ways to handle exceptions in our applications. In this tutorial, we will cover Controller Based Exception Handling using the @ExceptionHandler annotation above the method that will handle it.
  • Spring RESTful Web Service Example with JSON and Jackson using Spring Tool Suite
    For this example, I will be using Spring Tool Suite (STS) as it is the best integrated development environment for building the Spring framework projects. Spring is today's leading framework for building Java, Enterprise Edition (Java EE) applications. One additional feature that makes Spring MVC so appealing is that it now also supports REST (REpresentational State Transfer) for build Web Services.
  • Spring MVC RESTful Web Service Example with Spring Data for MongoDB and ExtJS GUI
    This post will show another example of how to build a RESTful web service using Spring MVC 4.0.6, Spring Data for MongoDB 1.6.1 so that we can integrate the web application with a highly efficient datastore (MongoDB 2.6). In this tutorial we will walk you through building the web service and NoSQL database backend and show you how to implement CRUD (Create, Read, Update and Delete) operations.
  • Building DHTMLX Grid Panel User Interface with Spring MVC Rest and MongoDB Backend
    In this tutorial we will show how easy it is to use DHTMLX dhtmlxGrid component while loading JSON data with Ajax pulling in data from the Spring MVC REST web service from our MongoDB data source. You will see how simple it is to create a visually appealing experience for your client(s) with minimal javascript coding.
  • Spring MVC with JNDI Datasource for DB2 on AS/400 using Tomcat
    In this tutorial we will discuss how to set up Spring MVC web services and configure a JNDI Datasource using Tomcat and connect to IBM DB2 Database on a AS/400. JNDI (Java Naming and Directory Interface) provides and interface to multiple naming and directory services.
  • Java Spring MVC Email Example using Apache Velocity
    In this tutorial we will discuss how to set up a Java Spring MVC RESTful Webservice with Email using Apache Velocity to create a Velocity template that is used to create an HTML email message and embed an image, as shown below, using MIME Multipart Message.
  • Implementing Basic and Advanced Search using Angular Material Design, Grid-UI, Spring MVC REST API and MongoDB Example
    In this tutorial we will discuss how to implement basic and advanced search techniques in MongoDB using AngularJS and Google’s Material Design with Spring MVC REST API backend. The advanced search user interface (UI) will use logical operators and build a JSON object which contains the search field name, boolean or logical operator and the search value.
  • Spring MVC Interceptor using HandlerInterceptorAdapter Example
    In this tutorial we will discuss how to use the HandlerInterceptorAdapter abstract class to create a Spring MVC interceptor. These interceptors are used to apply some type of processing to the requests either before, after or after the complete request has finished executing.

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *