Limiting the accessibility- Another way of Friend Assemblies

In my last post, I discussed, how to access internal class of one assembly in another assembly and that is easily achieved with the help of a C# feature called Friend Assemblies. It allows us to call the internal methods of another assembly. It is very much required at several occasions like the one I discussed in my last post, Unit Testing. It is often required to test the internal classes of the assembly in another project of Unit testing and It can be done easily via Friend Assembly.

To see my last post Please click here How to access internal class of one assembly to other assembly

But in some other scenarios Friend assemblies solution may not work. Like if you have two assemblies and one assembly accesses other assembly using Friend assembly. It’ll be fine as long as both assembly are compatible and shipped at same point of time. And if it does not happen on regular basis or in every release/update of assembly this may be hazardous.

To avoid it, we should implement it in another way. Here we declare the method as public but will limit to its accessibility to some specific assembly. It can be achieved by using LinkCommand with StrongNameIdentityPermission.

What is LinkCommand?

LinkCommand is a SecurityCommand which comes in the umbrella of Code Access Security(CAS). That allows you limit the accessibility of an assembly.

This can be applied at assembly, class and method level as well.

Here I’ll show you, how you can allow only the assembly that wants to call the method that will be able to execute it.
For this we need to follow the following steps:
1 – Create a project with a method that need to be called from another application
2 – Create another project that will be calling the method
3 – Sign the second assembly/project
4 – Get the public key.
5- Apply the StrongName attribute to the First assembly’s method with the public key of the second assembly
6 – Now call the method from second assembly

So lets go step by step:

1- Let’s create a First Project: Create a class library say named LinkDemandSample and It has a class named SampleClass. I have also created a method named SayHello. The class would look like as

    public class SampleClass
    {
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
    }
    

2- Create second project(Say created a console application named TestLinkDemand) that calls the method SayHello.
Currently SayHello method can be called to any assembly because it is public and it has not been limited for accessibility.

3- Now we need to sign the the second project that we’ll do using sn.exe.
First we need to create public/private key pair. This will be generated in .snk file. Use the below command

sn-k TestLinkDemand.snk

Then apply the this file to the assembly. Go to assembly info and add the following line
[assembly: AssemblyKeyFile(@'..\..\TestLinkDemand.snk')]

Or you can right click on project in solution explorer and click properties.

4- Now you assembly is signed but we need to get the public key because it is required for the SecurityCommand action.
Use the the following command which extracts the public key in a new file.

sn -p TestLinkDemand.snk TestLinkDemand.public

It will generate the public key in a new file TestLinkDemand.public but it is not readable because it is in
binary format. So to read the public command use the following command

sn -tp TestLinkDemand.public

5- Now we need to apply the StrongNameIdentityPermission attribute to the method as

   public class SampleClass
    {
        [StrongNameIdentityPermission(SecurityAction.LinkDemand, PublicKey =
            "00240000048000009400000006020000002400005253413100040000010001005f47ddff483a87" +
            "7b26c7fe31b029be4f6d6deeb149a5f732c548507fbce2bafa8bd7a6c04e078a5b7e069fad0222" +
            "27b7550fe15914fa03f35ef0a02f5c61f6a048c3e36ce304ebc407e1fb8962c56e27d4f0f691a2" +
            "05731e7c15b1565cdfcef03c9191e688834ac6d9f8e0a1a2651b9f5e291a68daea5475d233539e" +
            "cb9404a3")]
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
    }
    

6- Now this can be called only from second application. And if it is called by any other assembly. The following exception will be thrown

Hope you all have liked this.

Happy Coding
Brij

Advertisement

4 thoughts on “Limiting the accessibility- Another way of Friend Assemblies

  1. Hi
    i have very impressed with your articles i read your key skill your expertise in wcf .
    i have good knowledge on Wcf but i don’t know how to implement wcf concepts please send me one wcf project to
    raghava123@gmail.com
    thanking you

    • Hi Raghvendra,

      It’s nice to know that you have good knowledge in WCF. As you said that you don’t know How to implement those concepts. WCF is vast topic. I’ll suggest you to note down all the concepts that you know and start making practical samples on that. You can get a lot of samples and articles on internet. There are some good books are also available. I found ORieally and Apress one good.

      Hope it’ll help. If you stuck at any point Let me know, I’ll be happy to help you

  2. Unfortunately, this technique will not work as you seem to expect since .NET 2.0 changed the interpretation of full trust to include satisfying any identity permission demand (http://blogs.msdn.com/b/eugene_bobukh/archive/2005/05/06/415217.aspx). Use of InternalsVisibleToAttribute remains a far more reliable approach for restricting unintentional use of a semi-public API. (Nothing will protect your API from intentional misuse by a fully trusted caller, but InternalsVisibleToAttribute at least creates a situation where the caller will be aware of his potential misuse.)

  3. You are right. In case of full trust, you cannot limit the accessibility because the this check is kind of skipped. So one need to make sure the environment is not FullTrust.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s