How to forbid calling a method C#
Asked Answered
K

7

15

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?

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?

Kelleykelli answered 15/1, 2010 at 12:18 Comment(9)
If it's private, why does it matter?Oulman
How is this question voted up 9 times in just 6 minutes?Franciskus
Are you trying to protect you from yourself? Other than that I can't imagine the use for this.Dent
to Zakalwe No, its just a habit.Kelleykelli
@shoosh: And favourited twice?Oulman
@alga: It's extremely slow to do this, so if I were you, I would rethink this particular habit. At least for methods that are called frequently.Tautomerism
"I don't want to debate about design of application" - you came to the wrong place.Ronironica
to Thorarin. What is extremely slow? Access modifier? PS: the methods were called from method Main and I just copypasted it. Please don't pay attention to it and concentrate at the question.Kelleykelli
Jeff Sternal, I perfectly know what the place it is. Moreover if you don't have an answer for the question maybe you had better be silent?Kelleykelli
T
4

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.

Tactful answered 15/1, 2010 at 13:38 Comment(0)
I
24

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.

Inborn answered 15/1, 2010 at 12:28 Comment(0)
C
8

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.

Congruity answered 15/1, 2010 at 12:26 Comment(0)
T
7

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.

Tautomerism answered 15/1, 2010 at 12:32 Comment(0)
H
4

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);
Honeymoon answered 15/1, 2010 at 12:26 Comment(3)
+1; and seems to be possible encapsulate that by implementing CodeAccessPermissionExaggerated
yeah, I know about it. But I'm interesting how to do it with security attributes.Kelleykelli
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.)Audition
T
4

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.

Tactful answered 15/1, 2010 at 13:38 Comment(0)
L
3

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

Legrand answered 15/1, 2010 at 13:30 Comment(0)
F
2

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.

Flamsteed answered 15/1, 2010 at 12:37 Comment(1)
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 ^^Cantillate

© 2022 - 2024 — McMap. All rights reserved.