MongoDB authentication in Sitecore

Securing application data is critical for any client and business, and the same principle applies to Sitecore application as well.

One of the most important component of Sitecore is MongoDB, which is where we store all Experience(xDB) related data, MongoDB was shipped into Sitecore’s ecosystem from Sitecore 7.5, and it’s very important to make sure the data stored in xDB is secured, and only authorized uses has access to the data.

Recently, we heard about thousands of MongoDB data being hacked, so what’s the reason behind it? any guess? it’s simple- all those DBs were not configured to be secure and anyone can access it.

It would be great if MongoDB installation itself comes with an option, where we can secure our data while installing it, like how we do it for SQL.

Even though, we can go back and secure the data  by setting up users/roles and permissions, but it’s always great to do it it first place.

We also have to see and make sure that Connection string used for MongoDB is all protected with credentials, so that only authorized users can access it.

As part of this blog post, i would like to cover the steps which we can follow and make our Sitecore application more secure.

  1. Create MongoDB User
    1. Follow the below command to create the user.
    2. db.createUser({user: “mongoadmin”,pwd: “mongoadmin”,roles: [ { role: “userAdminAnyDatabase”, db:”admin” },{ role: “root”, db:”admin” }]})
    3. We just created a new mongouser- “mongoadmin” under database “admin”, and has given all rights to this user by assigning role “root“.
  2. Verifying the User
    1. If we want to verify that user gets created or not, we can use the following command for the same:
    2. db.auth(“mongoadmin”,”mongoadmin”)
    3. This should return 1, if the user is authenticated.
    4. We can also see the list of all users by running following command:
    5. db.getUsers()
  3. Assigning specific roles to unique collections
    1. We shouldn’t be giving “root” level access to the user, and it should be more specific to the database and collection.
    2. For example: we can give read and write access to analytics database in Sitecore.
    3. In order to do that, please login to mongo shell and switch to admin.
    4. use analytics
      db.createUser({user: “mongouser”,pwd: “mongopassword”,roles: [ { role: “readWrite“, db:”analytics” }]})

    5. In this case we created a new user called “mongouser” and assigned “readWrite” role to it, and is specific to “analytics” database.
    6. In the same way, we can do it for other three databases also.
  4. Connection string updates
    1. This is how the default connection string looks like:
    2. <add name=”analytics” connectionString=”mongodb://localhost:27017/sample_analytics” />
      <add name=”tracking.live” connectionString=”mongodb://localhost:27017/sample_tracking_live” />
      <add name=”tracking.history” connectionString=”mongodb://localhost:27017/sample_tracking_history” />
      <add name=”tracking.contact” connectionString=”mongodb://localhost:27017/sample_tracking_contact” />

    3. After making updates to connection string, and adding required username and password details to it, this is how it looks:
    4. <add name=”analytics” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_analytics?authSource=admin” />
      <add name=”tracking.live” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_live?authSource=admin” />
      <add name=”tracking.history” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_history?authSource=admin” />
      <add name=”tracking.contact” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_contact?authSource=admin” />

    5. This is how the format looks like:
    6. mongodb//[username:password@]host[:port]/database?authSource

If we are trying to access MongoDB without passing valid credentials, we get this error in the log, please see the screen shot for ref:

MongoAuthenticationFailed

Once we pass the valid credentials, this error will go off.

It’s always a good practice to authenticate MongoDB in local environment as well, this helps us in setting the habit for it and we can uncover any issues well in advance.

I hope this helps in getting the understanding about how we can secure and authenticate MongoDB, and how to create users/permissions for the same.

There is a great article in MongoDB documentation, around setting up auth for Mongo and setting up users, creating roles for the same, please consider reviewing this as well, this is great source of information.

https://docs.mongodb.com/manual/tutorial/enable-authentication/

Thanks, and please let me know for any questions, happy to discuss more.

Happy learning 🙂

Sitecore MongoDB Blog series: Part 2-Understand scaling, contacts and queries

In previous blog post we have gone through MongoDB introduction with Sitecore, features and installation.In this blog we will go over available scaling options in MongoDB, and then followed with introduction to contacts and out of the box queries.

Scaling:

There are three types of scaling:

  1. Standalone environment
  2. Vertical Scaling and
  3. Horizontal Scaling

Standalone environment:

A standalone is all in one configuration, where we install all xDB components in the same computer, which includes:

  • Content management server
  • Content delivery server
  • Database server
  • Reporting server
  • Collection server.

This is not an optimal production environment setup, and it’s mostly resembles the development environment, where we have all components in the same workstation, we can say this setup as “not scalable environment”.

standalone-setup

Vertical Scaling:

Vertical scaling means adding more resources to single node in the system,which typically involves adding/upgrading more hardware to single machine.

When we start inclining towards Vertical setup, we tend to have separate servers for each component, i.e separate servers for:

  • Database
  • Content management
  • Content delivery and
  • Reporting server

If we see that specific component requires hardware upgrade, then we can just scale that environment/component up, without touching any other server, and this way we can scale the complete Sitecore system.

Horizontal Scaling:

Though we can scale each component of the System, by following vertical Scaling, but what about if we have just one Content delivery server and because of some server issue, we lost all data from that server, just can’t imagine right?

In this specific case even we have scaled up the content delivery server by upgrading the size,RAM and all other component(s) as per the requirements, but such thing can’t help us out if something goes wrong with that specific server, which will ultimately results in data loss.

In this scenario, we can resolve the issue by deploying multiple servers for the same components, which includes:

  • Multiple content management servers
  • Multiple content delivery servers
  • Multiple MongoDB(Analytics) servers
  • Separate session state server.

This type of setup helps in resolving the issue of, one server going down for some reason, From MongoDB presepective, we can achieve this by adding multiple servers for Analytics, we do it via adding Replica sets.

By means of replication we achieve following:

  • Availability
  • MongoDB provides high data availability with replica sets.
  • A replica set consists of two or more copies of the same data.

What happens in Replica set is, we setup the environment which defines a primary server, which will be used to read and write the Analytics  information, at the same time all data from replicaset-1 will get copied to replicaset-2 and replicaset-3, all the servers are always in sync.

From here, if something goes wrong to replicaset-1 server, MongoDB internally makes either replicaset-2 or replicaset-3 as a primary source of reading and writing the information, this we can always make sure data availability.

horizontal-scalibility

Introduction to Contacts:

  • In xDB a contact is an individual visitor.
  • This visitor may be anonymous or he may have been authenticated.
  • A contact is a combination of facets.
  • Contact Includes:
    • Identifiers
    • Personal Information
    • Email
    • Phone Number
    • Addresses

contacts

Identifying Contacts:

  • Contact identification is the process of connecting the current session, device and contact session to an identifier. This is implemented using the Identify() method which is part of the Sitecore Analytics tracker namespace.
  • Sitecore.Analytics.Tracker.Current.Session.Identify(identifier)
  • A contact is always identified by an identifier, identifier is an string value which uniquely identifies a contact in relation to website and this value is always provided by contact itself.
  • Identifiers can be one of the following:
    • User login
    • User id from third party system and/or
    • Email address

Here is the sample snippet which shows how we can validate the use in MongoDB:

mongo-validate-user

MongoDB Queries:

Let’s look into the sample two queries, which is used to fetch data from out of the collections.

Consider a case where we have millions of records in “Contacts” collection, and wants to get specific contact record, we can add a filter where we can pass “FirstName”, and we use “Personal.Firstname” Facet for this.

db.getCollection(‘Contacts’).find({“Personal.FirstName”:”Ankit Joshi”})

FirstNameFilter

Another example, if we want to find an identifier based on specific Id, we can use this query:

db.getCollection(‘Identifiers’).find({“_id”:”ANKIT”})

IdentifyFilter

In the same way we can also create custom collections, and add documents to it using Mongo Shell.

We can create custom collections using Mongo Shell, and the beauty of this is, when we try to create a new collection, and if that collection doesn’t exists it will create it automatically, and documents of the collections can have different structure, which makes it more flexible.

Let me know your feedback and comments if any?

References:

https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/xdb/platform/scalability_options

Happy learning 🙂