security exception

Topics: Writing modules
May 24, 2011 at 3:01 PM

Hi, I'm trying to reference some code in one my own dlls in my Orchard modules (a client for some JSON services) however the site is now falling over on startup with this error:

[SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
   System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) +0
   System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark) +31
   System.Security.CodeAccessPermission.Demand() +46
   System.Reflection.RuntimeAssembly.get_Location() +100
   Orchard.Environment.Extensions.Loaders.ReferencedExtensionLoader.Probe(ExtensionDescriptor descriptor) +96
   Orchard.Environment.Extensions.<>c__DisplayClass38.b__14(IExtensionLoader loader) +15
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
   System.Linq.WhereEnumerableIterator`1.MoveNext() +154
   System.Linq.d__14`2.MoveNext() +295
   System.Linq.Lookup`2.Create(IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer) +266
   System.Linq.GroupedEnumerable`3.GetEnumerator() +61
   System.Linq.Enumerable.ToDictionary(IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer) +151
   Orchard.Environment.Extensions.ExtensionLoaderCoordinator.CreateLoadingContext() +1591
   Orchard.Environment.Extensions.ExtensionLoaderCoordinator.SetupExtensions() +87
   Orchard.Environment.DefaultOrchardHost.BuildCurrent() +91
   Orchard.Environment.DefaultOrchardHost.Orchard.Environment.IOrchardHost.Initialize() +57
   Orchard.Web.MvcApplication.Application_Start() +113

Any idea what could be causing it? I thought it might be ConfigurationManager so have removed references to this but I'm still getting the problem. The code originally lived in an actual Orchard Module where it worked fine but now its moved to a class library I get these problems.

thanks for any input

Nic

Coordinator
May 24, 2011 at 4:16 PM
Edited May 24, 2011 at 4:47 PM

I think you are running into a bug related to Medium Trust (Accessing the "Location" property is not allowed under medium trust). It looks like you copied one (or more) module assembly file to the "~/bin" folder and Orchard is trying to load the module assembly from there. Note: Usually, this is not how modules are loaded: they are either dynamically compiled or loaded from the "~/App_Data/Dependencies" folder, which is why nobody has run into this bug before, i believe.

I see 3 options:

  • Remove "Trust Level='Medium'" from your web.config. You don't need this (and probably want to remove it for performance reason) unless you are deploying on a shared hoster which only support Medium Trust.
  • Don't copy the module assembly file to "~/bin" (i.e. leave it in "~/Modules/<MyModule>/bin"). Orchard should be able to load your module automatically from it original location in "~/Modules". (Let us know if you run into problems though)
  • Change the source code of ReferencedExtensionLoader.Probe and re-compile Orchard.Framework.dll

Change this:

 

to

 I opened a bug to track this: http://orchard.codeplex.com/workitem/17869

 HTH,

Renaud

            string assemblyPath = _virtualPathProvider.Combine("~/bin", descriptor.Id + ".dll")
            return new ExtensionProbeEntry {
                Descriptor = descriptor,
                LastWriteTimeUtc = _virtualPathProvider.GetFileLastWriteTimeUtc(assemblyPath),
                Loader = this,
                VirtualPath = assemblyPath
            };

            return new ExtensionProbeEntry {
                Descriptor = descriptor,
                LastWriteTimeUtc = File.GetLastWriteTimeUtc(assembly.Location),
                Loader = this,
                VirtualPath = _virtualPathProvider.Combine("~/bin", descriptor.Id + ".dll")
            };
May 25, 2011 at 8:40 AM

I'm not copying any modules to bin. Sorry I'll try and be more specific, we're actually doing something a bit cheeky. We want to inject some services into the Orchard.Users module. So I have a separate dll which is referenced by the Orchard.Users module. This dll gets copied to ~/bin by Orchard when it compiles the modules (I'm guessing). So if I remove Medium Trust I get the following error instead:

Attempt by security transparent method 'Orchard.Users.Controllers.AccountController..ctor(Orchard.Security.IAuthenticationService, Orchard.Security.IMembershipService, Orchard.Users.Services.IUserService, Orchard.IOrchardServices, Smart.Services.Client.IEmailService, Smart.Services.Client.IUserService)' to access security critical type 'Smart.Services.Client.IEmailService' failed.

I'm guessing the Orchard.Users module runs under different trust? Any more ideas?

 

thanks

Nic

May 25, 2011 at 12:00 PM

And the plot thickens - I've now upgraded to 1.1.3 and this has had the effect that none of my own DLLs get loaded by my modules.

Example:

My Module - Smart.Packages which has a reference ((in the csproj file) to another one of my DLLs - Smart.Domain.

The module is enabled but when I browse to it I get an error saying I'm missing a reference to the Smart.Domain.dll

May 25, 2011 at 12:50 PM

That doesn't sound like the right way to do it!

Can you explain exactly what you're trying to achieve when you say "inject some services" ... usually that's achieved via dependency injection which you use from anywhere. Maybe there's a far more "standard" way to achieve your desired end result.

May 25, 2011 at 12:55 PM

When the user verifies their account we need to do some additional work calling some of our external services. We're using dependency injection to inject our services into the controller.

 

thanks for any ideas.

Nic

May 25, 2011 at 1:31 PM

Can't you just implement IUserEventHandler, and perform that work on the ConfirmedEmail event? You can do this entirely from your own module without having to mess with the users controller...

May 25, 2011 at 1:38 PM

Yep - looks like it will do the job - thanks. Didn't exist in 1.0 though!. Now I just have this issue of not being able to load my modules dependent dlls. Any ideas?

May 25, 2011 at 2:11 PM

I can add some more detail - the module fires up fine, controller is fine but on rendering a razor template it then complains (in ViewEngineCollectionWrapper) it knows nothing about the type or which is in Smart.Domain???

May 25, 2011 at 3:55 PM

Where is the assembly located - in the bin folder of your module, or have you put it elsewhere?

Does changing trust level to Full clear the problem?

May 25, 2011 at 4:09 PM

OK another update:

copying the dependent dll to ~/bin fixed the issue with the views not seeing the assembly.

however I still have an issue when trying to inject dependencies into my Module controllers - if the dependency (which is marked as an IDependency) is in a referenced DLL rather than another orchard module the IoC fails to resolve the dependency. We've tried adding it to the Modules bin directory and to ~/bin. To no avail.

 

thanks for your help on this - its been a trying day!

May 25, 2011 at 6:12 PM

I guess Autofac is only looking in modules themselves for dependencies. There will almost certainly be a way to tell it to inspect other dlls; but obviously this isn't normally desirable, it'd be an unneccessary performance hit to go checking NHibernate, System.Web, MVC, etc. for dependencies when there won't be any.

I should point out that if your dll is referencing Orchard then actually you should just implement it as a module, instead of jumping through hoops essentially trying to get Orchard to recognise it as a module without it having a Module.txt manifest file. What exactly is your reason for wanting it as a class library instead of a module if it has a dependency on Orchard anyway?

May 25, 2011 at 6:20 PM

Absolutely fair point. I don't want it to depend on orchard but I need the classes to be injected via ioc into my orchard modules. Is there another way to do it other than use IDependency?

agileX ltd.

May 25, 2011 at 6:34 PM

You could probably start messing around with Autofac at a much lower lever to tell it to inject those specific dependencies. But it all seems a bit topsy turvy, and I wonder what is the use of having IoC if you're just using it to inject specific external dependencies anyway?

You could always create an Orchard module that just contains IDependency wrappers around the classes you're after...