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
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
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
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.)
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.