Details
-
Bug
-
Resolution: Done
-
Major - P3
-
None
-
2.10.4
-
None
-
(copied to CRM)
Description
Steps to reproduce (using Visual Studio 2019 and a local MongoDB 4.2-ent cluster)
1 - Create an ASP.NET Web Application / Web API project
2 - Enable Tools > Options > Project and Solutions > Web Projects and check the option > "Use the 64 bit version of IIS Express for web sites and projects"
3 - Set the project's Platform Target to x64
3 - Using the NuGet Package Manager, install MongoDB.Driver (2.10.4) and MongoDB.Libmongocrypt (1.0.0)
4 - Copy the following code to Controllers\ValuesController.cs:
using MongoDB.Bson; |
using MongoDB.Driver; |
using MongoDB.Driver.Encryption; |
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Threading; |
using System.Web.Http; |
|
|
namespace WebApplication1.Controllers |
{
|
public class ValuesController : ApiController |
{
|
private MongoClient GetCSFLEClient() |
{
|
var localMasterKey = Convert.FromBase64String("Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk"); |
|
|
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); |
var localKey = new Dictionary<string, object> |
{
|
{ "key", localMasterKey } |
};
|
kmsProviders.Add("local", localKey); |
|
|
var keyVaultNamespace = CollectionNamespace.FromFullName("admin.datakeys"); |
var keyVaultMongoClient = new MongoClient(); |
var clientEncryptionSettings = new ClientEncryptionOptions( |
keyVaultMongoClient,
|
keyVaultNamespace,
|
kmsProviders);
|
|
|
var clientEncryption = new ClientEncryption(clientEncryptionSettings); |
var dataKeyId = clientEncryption.CreateDataKey("local", new DataKeyOptions(), CancellationToken.None); |
var base64DataKeyId = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard)); |
clientEncryption.Dispose();
|
var schemaMap = $@"{{ |
properties: {{
|
encryptedField: {{
|
encrypt: {{
|
keyId: [{{
|
'$binary' : {{
|
'base64' : '{base64DataKeyId}',
|
'subType' : '04'
|
}}
|
}}],
|
bsonType: 'string',
|
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
|
}}
|
}}
|
}},
|
'bsonType': 'object'
|
}}"; |
|
|
var collectionNamespace = CollectionNamespace.FromFullName("test.coll"); |
|
|
var autoEncryptionSettings = new AutoEncryptionOptions( |
keyVaultNamespace,
|
kmsProviders,
|
schemaMap: new Dictionary<string, BsonDocument>() |
{
|
{ collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
|
});
|
|
|
var clientSettings = new MongoClientSettings |
{
|
AutoEncryptionOptions = autoEncryptionSettings
|
};
|
|
|
return new MongoClient(clientSettings); |
}
|
|
|
// GET api/values |
public IEnumerable<string> Get(bool csfle) |
{
|
var client = (csfle) ? GetCSFLEClient() : new MongoClient(); |
var database = client.GetDatabase("test"); |
database.DropCollection("coll"); |
var collection = database.GetCollection<BsonDocument>("coll"); |
|
|
collection.InsertOne(new BsonDocument("encryptedField", "123456789")); |
|
|
var result = collection.Find(FilterDefinition<BsonDocument>.Empty).First(); |
|
|
return new string[] { result.ToJson() }; |
}
|
}
|
}
|
5 - Build / Run
Using the following should succeed:
https://localhost:44373/api/Values?csfle=false
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> |
<string>{ "_id" : ObjectId("5ed63b324eecb9086ccccaf2"), "encryptedField" : "123456789" }</string> |
</ArrayOfstring> |
Using the following should fail:
https://localhost:44373/api/Values?csfle=true
<Error> |
<Message>An error has occurred.</Message> |
<ExceptionMessage> |
Could not find: mongocrypt.dll -- Tried: C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\..\..\x64\native\windows\mongocrypt.dll,C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\mongocrypt.dll
|
</ExceptionMessage> |
<ExceptionType>System.IO.FileNotFoundException</ExceptionType> |
<StackTrace> |
at MongoDB.Libmongocrypt.LibraryLoader.FindLibrary(IList`1 basePaths, String[] suffixPaths, String library) at MongoDB.Libmongocrypt.LibraryLoader..ctor() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_46() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_1() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.CryptClientFactory.Create(CryptOptions options) at MongoDB.Driver.Core.Clusters.CryptClientCreator.CreateCryptClient(IReadOnlyDictionary`2 kmsProviders, IReadOnlyDictionary`2 schemaMap) at MongoDB.Driver.Encryption.ClientEncryption..ctor(ClientEncryptionOptions clientEncryptionOptions) at WebApplication1.Controllers.ValuesController.GetCSFLEClient() in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 32 at WebApplication1.Controllers.ValuesController.Get(Boolean csfle) in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 75 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext() |
</StackTrace> |
</Error> |