Azure AD Integration

This year I’ve been working a lot more with Azure. On of my tasks has been to integrate other application to each other using Azure AD. Here are some of my finding and good to know things in case someone else runs into them:

  • Create a new MVC Application in Visual Studio
  • When this is done, press the second mouse button on the project and go to “Add” > “Connected Services”. This will allow you to create an O365 connection.
  • Select Office 365 API Services.
  • In the new Window select or type in your domain.
  • Next, create new Azure AD application configuration or use an existing one by providing the GUID for the application.
    • Make sure you select the “Configure Single Sign-On using Azure AD” option
    • Make sure that your application is multi-tenant:
      • This works so that you register your app with you own Azure AD domain, then after that external Azure AD tenants and their users are registered through an “onboarding” process. The process will the user or admin user for privileges to use certain information from the AD or other resources. These are defined in the Azure AD application settings.
      • Notice you are using an application ID and key to connect to your own organization Azure AD then the users are only onboarding using the multi-tenant option in the Azure AD application configuration.
    • Next select what kind of privileges your application needs from the Azure AD and O365.
    • You need onboarding functionality from here: https://azure.microsoft.com/en-us/documentation/samples/active-directory-dotnet-webapp-multitenant-openidconnect/
    • In Global.asax.cs application_start function add the following: AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
      • If this is missing, then you claim will not work properly.
    • If you are using a SQL Server database and Entity Framework remember to update you model from the database and remember primary key connections. If the Entity Framework update does not work then removing and adding the database tables should force an update. Also remember to clean and build your project if nothing else helps.
    • If you get this error: Error: {“error”:”invalid_grant”,”error_description”:”AADSTS70002: Error validating credentials. AADSTS70000: The provided access grant is invalid or malformed…..
    • Doing a redirect the proper way in an MVC apllication using the following piece of code in your contoller: return Redirect(returnUrl);
      • If you use the normal way in ASP .NET: Response.Redirect(returnUrl); you will run into trouble. The error message might look something like this:
        • Server Cannot Append Header After HTTP headers have been sent Exception at @Html.AntiForgery
        • You could set the AntiForgeryConfig.SuppressXFrameOptionsHeader = true; in the Application_start, but this will lower your security and not advisable.

 

Advertisements

MongoDB Magic a.k.a simple database operations

Hi,

This is my little post on how to do simple database operations with MongoDB.

First let’s start with needed MongoDB needed functionalities. The simplest way is to open Visual Studio and manage your projects nugets packages. Add these four nuggets to your projects. Notice that you do not necessary need the mongocshaprdiver, it’s a legacy driver. Add it only if you need it.

mongodbnugets

Next to be able to use the classes for handling MongoDB database operation include the following namespaces:

using MongoDB.Bson;
using MongoDB.Driver;

BSON is: “BSON is a binary serialization format used to store documents and make remote procedure calls in MongoDB” More info here: https://docs.mongodb.com/manual/reference/bson-types/

Driver is: “The official MongoDB C#/.NET Driver provides asynchronous interaction with MongoDB” More Info: https://docs.mongodb.com/ecosystem/drivers/csharp/

To code below will create a client connection to the MondoDB and will get a database in it.

var client = new MongoClient("mongodb://localhost:27017");
 var database = client.GetDatabase("databaseName");

To list all collections in a database:

foreach (var item in database.ListCollectionsAsync().Result.ToListAsync<BsonDocument>().Result)
 {
}

 

To get the name of the collection:

var name = item.Elements.FirstOrDefault().Value.RawValue as String;

To access a collection and all of its documents:

var collection = database.GetCollection<BsonDocument>(name);
// This filter simply means that all data is retrieved
 var filter = new BsonDocument();

 var documents = collection.Find(filter);
 {
 {
 foreach (var document in documents.ToEnumerable())
 {
 }
}
}

To check if a document has elements(fields) with a certain data type:

var dateTimeFields = document.Elements.Where(o => o.Value.BsonType == BsonType.DateTime);
foreach (var dateTimeField in dateTimeFields)
 {
}

To update a document with certain values:

var updateFilter = Builders<BsonDocument>.Filter.Eq("_id", document.Elements.FirstOrDefault().Value);
 var value = BsonTypeMapper.MapToDotNetValue(dateTimeField.Value);
 var updateDefiniotion = Builders<BsonDocument>.Update.Set(dateTimeField.Name, BsonTypeMapper.MapToBsonValue(((DateTime)value).AddDays(3)));

 var result = collection.UpdateOne(updateFilter, updateDefiniotion);
 if (result.ModifiedCount > 0)
 {
 // Success
 }
 else
 {
 // No updates
 }

Retrieving documents based on a filter and copying them into another collection + deleting from the original collection:

var timeEntriesIntoTheFuture = Builders<BsonDocument>.Filter.Gt(dateTimeField.Name, BsonTypeMapper.MapToBsonValue(DateTime.Now));
 var entries = sourceCollection.Find(timeEntriesIntoTheFuture);
if(entries.Count() > 0)
 {
tempTimeEntryCollection.InsertMany(entries.ToEnumerable());
 foreach(var entry in entries.ToEnumerable())
 {
 sourceCollection.DeleteOne(entry);
 }
}

Checking if a collection exists:

public static bool DoesCollectionExist(IMongoDatabase database, String collectionName)
 {
 bool collectionExists = false;

 foreach (var item in database.ListCollectionsAsync().Result.ToListAsync<BsonDocument>().Result)
 {
 var name = item.Elements.FirstOrDefault().Value.AsString;
 if (name.Contains(collectionName))
 {
 collectionExists = true;
 break;
 }
 }

 return collectionExists;
 }

Updating an element at a certain position:

var updateDefiniotion = Builders<BsonDocument>.Update.Set(firstDocument.ElementAt(1).Name, BsonTypeMapper.MapToBsonValue(DateTime.Now));

Inserting a document in a manually defined manner:

var dateTimeStampeValue = new BsonDocument()
{
{ "ResetDate", BsonTypeMapper.MapToBsonValue(DateTime.Now) }
};
settingsCollection.InsertOne(dateTimeStampeValue);