How can I check and make sure that a class uses my own custom security attribute? I know that I can use reflection to get normal attributes, but if the custom attribute is based on a security attribute as shown below reflection doesn't show it. Is there any way to check that?
Why I would need this is to make sure that a plugin that is loaded to a cloud based system must use security attribute so the class that get's loaded cannot access any restricted files and so on.
Here is the custom security class I'm using:
public class PluginSection : CodeAccessSecurityAttribute
{
public PluginSection(SecurityAction action)
: base(action)
{
}
public override IPermission CreatePermission()
{
// WebSites.GetInstance().LocalBaseDir returns the base directory where the class has accesss to login
return new FileIOPermission(FileIOPermissionAccess.Write, WebSites.GetInstance().LocalBaseDir);
}
}
I must use a class based on CodeAccessSecurityAttribute so that the FileIOPermission would work.
Also if there is another way to restrict the access of the plugin being loaded I could use that too.
Reflection seems to work fine for me:
using System;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;
public class PluginSection : CodeAccessSecurityAttribute
{
public PluginSection(SecurityAction action)
: base(action)
{
}
public override IPermission CreatePermission()
{
// Removed for demo purposes
return null;
}
}
class NotApplied {}
[PluginSection(SecurityAction.Demand)]
class Applied{}
class Test
{
static void Main()
{
Console.WriteLine(IsPluginSection(typeof(Applied)));
Console.WriteLine(IsPluginSection(typeof(NotApplied)));
}
static bool IsPluginSection(Type type)
{
return type.IsDefined(typeof(PluginSection), false)
}
}
I don't think it is necessary to use reflection to check, if an attribute is assigned to the plugin. Permissions is based on scope, so they will propagate downwards in your call hierarchy.
If it is possible with your current design, you should just decorate the method that executes your code with the custom attribute:
[SomePermission(SecurityAction.PermitOnly)]
public void PluginExecutor(Plugin plugin)
{
plugin.Something();
}
Something
will only be given the same rights as your PluginExecutor
method. Therefore you can assign whatever permissions at this point, without worrying if the plugin uses them - and without having to rely on reflection.
I don't have an answer, but if it gives people more information to reproduce the issue:
[TestFixture]
public class SecurityExperiments
{
[Test]
public void ShouldGetCustomSecurityAttributes()
{
Assert.That(typeof (Applied).GetCustomAttributes(true),
Has.Some.InstanceOf<PluginSection>());
}
public class PluginSection : CodeAccessSecurityAttribute
{
public PluginSection(SecurityAction action)
: base(action)
{
}
public override IPermission CreatePermission()
{
// Removed for demo purposes
return null;
}
}
[PluginSection(SecurityAction.Demand)]
class Applied { }
}
Causes (for my test project, at least):
System.TypeLoadException: Could not load type 'PluginSection' from assembly 'StackOverflow, Version=1.0.0.0, Culture=neutral'.
at System.Reflection.PseudoCustomAttribute._GetSecurityAttributes(Void* module, Int32 token, Object[]& securityAttributes)
at System.Reflection.PseudoCustomAttribute.GetCustomAttributes(RuntimeType type, Type caType, Boolean includeSecCa, ref Int32 count)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.RuntimeType.GetCustomAttributes(Boolean inherit)
at StackOverflow.SecurityExperiments.ShouldGetCustomSecurityAttributes() in SecurityExperiments.cs: line 13