IndexCreation.CreateIndexes and GlobalAdmin.EnsureDatabaseExists failing against embedded database when AnonymousUserAccessMode is None (version 3.0.3800)

48 views
Skip to first unread message

jacob schuetze

unread,
Jan 19, 2017, 2:29:29 PM1/19/17
to RavenDB - 2nd generation document database
I'm trying to change how we initialize the embedded RavenDB for our product.  In the past, we have just included the following during initialization:

store.Configuration.Settings["Raven/Licensing/AllowAdminAnonymousAccessForCommercialUse"] = "true";
store.Configuration.AnonymousUserAccessMode = AnonymousUserAccessMode.Admin;

We do not want anonymous users to have much/any access, especially when we have Studio enabled.  I've changed the setup so that AnonymousUserAccessMode = AnonymousUserAccessMode.None.  I have also set AllowLocalAccessWithoutAuthorization = false, but in testing, setting this to true didn't help.

I'm now having some problems with initialization.  After ensuring the Raven system database is in place, we commonly create multiple tenants.  We have separate tenants for different parts of our application we want to keep separate, plus one for NServiceBus.  After the databases are configured, we initialize NServiceBus and point it at its own tenant.  At different points in this setup, both our code and the NServiceBus code call IndexCreation.CreateIndexes or IDocumentStore.ExecuteIndex.  Those calls, as well as calls to EnsureDatabaseExists on the system store are failing with this error:

System.Security.SecurityException: Attempted to connect to a RavenDB Server that requires authentication using Windows credentials,
but either wrong credentials were entered or the specified server does not support Windows authentication.
If you are running inside IIS, make sure to enable Windows authentication.

I'm looking for some guidance on how to do this in a production environment, since setting AnonymousUserAccessMode.Admin is clearly not what should be done.


Here is some C# / Xunit code I pulled together to show fairly minimalistic failing scenarios:


using System;
using System.Collections.Specialized;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Raven.Abstractions.Data;
using Raven.Client.Embedded;
using Raven.Client.Indexes;
using Raven.Database.Server;
using Xunit;

namespace RavenTests
{
public class DbInitTests
{
[Fact]
public void TestInitWithIndexes()
{
var dbRoot = "d:\\temp\\raventests\\t_" + DateTime.Now.Ticks;
var dbKey = Convert.ToBase64String(Encoding.UTF8.GetBytes(@"a key string"));

// embedded db with encryption, compression, and with specified folders
var store = new EmbeddableDocumentStore
{
DataDirectory = dbRoot,
Configuration =
{
DatabaseName = "testdb",
AnonymousUserAccessMode = AnonymousUserAccessMode.None,
AllowLocalAccessWithoutAuthorization = true,
Settings = new NameValueCollection()
{
{"Raven/WorkingDirectory", dbRoot},
{"Raven/AssembliesDirectory", Path.Combine(dbRoot, "Assemblies")},
{"Raven/CompiledIndexCacheDirectory", Path.Combine(dbRoot, "CompiledIndexCache")},
{"Raven/ActiveBundles", "Encryption;Compression" },
{"Raven/License", OurRavenLicense.LicenseText() },
{Constants.EncryptionKeySetting, dbKey}
}
},
};

// overriding the settings above with these settings allows the index creation to succeed
//---------------------------------------------------------------------------------------------------
//store.Configuration.Settings["Raven/Licensing/AllowAdminAnonymousAccessForCommercialUse"] = "true";
//store.Configuration.AnonymousUserAccessMode = AnonymousUserAccessMode.Admin;
//---------------------------------------------------------------------------------------------------

store.Initialize();

var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var provider = new CompositionContainer(catalog);

/* fails with: 
System.Security.SecurityException: Attempted to connect to a RavenDB Server that requires authentication using Windows credentials,
but either wrong credentials were entered or the specified server does not support Windows authentication.
If you are running inside IIS, make sure to enable Windows authentication.
*/
IndexCreation.CreateIndexes(provider, store.DatabaseCommands, store.Conventions);
}

[Fact]
public void TestInitWithTenant()
{
var dbRoot = "d:\\temp\\raventests\\t_" + DateTime.Now.Ticks;
var dbKey = Convert.ToBase64String(Encoding.UTF8.GetBytes(@"a key string"));

// embedded db with encryption, compression, and with specified folders
var store = new EmbeddableDocumentStore
{
DataDirectory = dbRoot,
Configuration =
{
DatabaseName = "testdb",
AnonymousUserAccessMode = AnonymousUserAccessMode.None,
AllowLocalAccessWithoutAuthorization = true,
Settings = new NameValueCollection()
{
{"Raven/WorkingDirectory", dbRoot},
{"Raven/AssembliesDirectory", Path.Combine(dbRoot, "Assemblies")},
{"Raven/CompiledIndexCacheDirectory", Path.Combine(dbRoot, "CompiledIndexCache")},
{"Raven/ActiveBundles", "Encryption;Compression" },
{"Raven/License", OurRavenLicense.LicenseText() },
{Constants.EncryptionKeySetting, dbKey}
}
},
};

// overriding the settings above with these settings allows the tenant creation to succeed
//---------------------------------------------------------------------------------------------------
//store.Configuration.Settings["Raven/Licensing/AllowAdminAnonymousAccessForCommercialUse"] = "true";
//store.Configuration.AnonymousUserAccessMode = AnonymousUserAccessMode.Admin;
//---------------------------------------------------------------------------------------------------

store.Initialize();

/* fails with: 
System.Security.SecurityException: Attempted to connect to a RavenDB Server that requires authentication using Windows credentials,
but either wrong credentials were entered or the specified server does not support Windows authentication.
If you are running inside IIS, make sure to enable Windows authentication.
*/
store.DatabaseCommands.GlobalAdmin.EnsureDatabaseExists("nsb");  // create tenant to later feed to NServiceBus for Raven persistence
}
}

public class Simpleton
{
public Guid Id { get; set; }
public string TextProp { get; set; }
public int IntProp { get; set; }
}

public class AssessmentFunction_InputUsages : AbstractIndexCreationTask<Simpleton>
{
public class Result
{
public string IxKey { get; set; }
}

public AssessmentFunction_InputUsages()
{
Map =
simpletons =>
from doc in simpletons
select new
{
IxKey = doc.Id + doc.TextProp + doc.IntProp
};
}
}
}


Thanks,
Jacob

Oren Eini (Ayende Rahien)

unread,
Jan 19, 2017, 3:02:02 PM1/19/17
to ravendb
You setup the server to reject anonymous calls, and you get an error with regards to authentication.
You are using embedded, so this isn't on IIS, so we have windows auth enabled.

This might be related to this: 

If you setup a _new_ document store and point it at the embedded server, does it work?
What happens if you use the machine name as the url? 
What happens if you do that from an external machine?

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jacob schuetze

unread,
Jan 19, 2017, 7:04:52 PM1/19/17
to RavenDB - 2nd generation document database

We have never created separate 'real' document store objects for the tenants, we always used the EmbeddableDocumentStore (or a wrapper around it for tenants which intercepts OpenSession calls and does OpenSession(tenantName) instead, otherwise delegating all work to the underlying system database).

Based on your questions, I started playing around a little bit, and this works:


[Fact]
public void TestInitWithTenantUsingSeparateTenantStore()
{
var dbRoot = "d:\\temp\\raventests\\t_" + DateTime.Now.Ticks;
var dbKey = Convert.ToBase64String(Encoding.UTF8.GetBytes(@"a key string"));

var testPort = 9123;

// embedded db with encryption, compression, and with specified folders
using(var store = new EmbeddableDocumentStore
{
DataDirectory = dbRoot,
UseEmbeddedHttpServer = true,
Configuration =
{
Port = testPort,
DatabaseName = "testdb",
AnonymousUserAccessMode = AnonymousUserAccessMode.None,
AllowLocalAccessWithoutAuthorization = false,
Settings = new NameValueCollection()
{
{"Raven/WorkingDirectory", dbRoot},
{"Raven/AssembliesDirectory", Path.Combine(dbRoot, "Assemblies")},
{"Raven/CompiledIndexCacheDirectory", Path.Combine(dbRoot, "CompiledIndexCache")},
{"Raven/ActiveBundles", "Encryption;Compression"},
{"Raven/License", OurRavenLicense.LicenseText()},
{Constants.EncryptionKeySetting, dbKey}
}
},
})
{
store.Initialize();

// using (var nsbStore = new DocumentStore { Url = $"http://localhost:{testPort};Database=nsb" }) // this fails with what looks like a parsing error for some reason...
using (var nsbStore = new DocumentStore { Url = $"http://localhost:{testPort}" })
{
nsbStore.DefaultDatabase = "nsb";
nsbStore.Initialize();
using(var s = nsbStore.OpenSession())
{
s.Store(new { SomeProp = "abc", SomeOtherProp = 123 });
s.SaveChanges();
}
}
}
}

I will need to try some more things using this kind of approach, but it may improve a few things for us if it works.


Thanks!


On Thursday, January 19, 2017 at 12:02:02 PM UTC-8, Oren Eini wrote:
You setup the server to reject anonymous calls, and you get an error with regards to authentication.
You are using embedded, so this isn't on IIS, so we have windows auth enabled.

This might be related to this: 

If you setup a _new_ document store and point it at the embedded server, does it work?
What happens if you use the machine name as the url? 
What happens if you do that from an external machine?

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


On Thu, Jan 19, 2017 at 9:29 PM, jacob schuetze <jacob.s...@gmail.com> wrote:

 <snipped>
...

Thanks,
Jacob

--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Oren Eini (Ayende Rahien)

unread,
Jan 20, 2017, 4:46:41 AM1/20/17
to ravendb
// using (var nsbStore = new DocumentStore { Url = $"http://localhost:{testPort};Database=nsb" }) // this fails with what looks like a parsing error for some reason...

That isn't the url.
You are trying to pass a connection string here.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages