views:

421

answers:

7

I want to allow calling the method only from the particular methods. Take a look at the code below.

  private static void TargetMethod()
  {
  }

  private static void ForbiddenMethod()
  {
     TargetMethod();
  }

  private static void AllowedMethod()
  {
     TargetMethod();
  }

I need only AllowedMethod could call TargetMethod. How to do it using classes from System.Security.Permissions?

Thanks.

Updated: Thanks for your answers, but I don't want to debate about design of my application. I just want to know is it possible to do it using .net security or not?

+5  A: 

I believe you should try to structure your code in meaningfull classes, and use the standard access modifiers (private, protected, public, internal). Is there any specific reason why this would not solve your problem?

The only alternative I can think of, would involve traversing the call stack from within the callee, but that would likely yield code mess and suboptimal performance.

Jørn Schou-Rode
+3  A: 

I am not sure if this is achievable with System.Security.Permissions, but inside TargetMethod you could get the caller and act accordingly:

StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Darin Dimitrov
+1; and seems to be possible encapsulate that by implementing `CodeAccessPermission`
Rubens Farias
yeah, I know about it. But I'm interesting how to do it with security attributes.
alga
This technique is slow and potentially fragile: Method inlining by the JITter could cause the `GetMethod` call to return unexpected results. (You can, of course, tell the JITter not to inline, as in Thorarin's answer.)
LukeH
+18  A: 

You can solve this using normal object-oriented design. Move AllowedMethod to a new class and make ForbiddenMethod a private method of that class:

public class MyClass
{
    public void AllowedMethod() { // ... }

    private void TargetMethod() { // ... }
}

AllowedMethod has access to private members, but no-one else have.

Mark Seemann
+4  A: 

You could examine the call stack to accomplish this, but it is rather slow. I wouldn't recommend it if it can be avoided.

Should you still want to do this, you need to be careful to avoid method inlining as well, or your code might suddenly stop working under Release builds.

[MethodImpl(MethodImplOptions.NoInlining)]
private static void TargetMethod()
{
    StackFrame fr = new StackFrame(1, false);
    Console.WriteLine(fr.GetMethod().Name);
}

As far as I know, there are no out-of-the-box attributes to do this.

Thorarin
+2  A: 

By using Attributes you can solve this issue.

Use Conditional Attributs.

In the top

#define "Show" 


  public void TargetMethod()
    {
      //Code
    }
   [ Conditional("Hidden")]
   public void HiddenMethod()
    {
       TargetMethod()
    }
 [ Conditional("Show")]
  public void AllowMethod()
    {
       TargetMethod()
    }

One of your methos will be called.

Vibin Jith
Well that removes `HiddenMethod` altogether. I think what alga wants, is to choose a select few methods that are allowed to call `TargetMethod` while denying *all others*, including ones in 3rd-party code, to call `TargetMethod`. Conditional compilation won't help achieve this ^^
SealedSun
+3  A: 

You might be able to use CodeAccessPermission objects. You'd have to implement the interface in your own object to have it work like you're suggesting though.

http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.aspx

Joel Etherton
+3  A: 

CAS cannot do this if the code is running in full trust.

If the code is executing in Full Trust (i.e. a normal, local application, not a silverlight application or something run from the network), then all .NET CAS checks are completely bypassed; any security attribute is simply ignored.

CAS simply walks the stack to determine permissions, though, and you can do that too, as Darin pointed out earlier by just checking the StackTrace.

Eamon Nerbonne