Hi Forum
I have the following problem. I need to know whether a call to a business object was made from another business object or directly from the UI. I need this because of Security and Logging reasons.
Security - Users might not have permission to call the method on a business object. But another business object might need to call it. - But it's the same method :(
Logging - I often want to log when a user performs an action. Another business object might also perform that action but then I don't what to log it. But it is the same method. ;(
The best solution I have found is to make an internal version of the method with parameters. Like this:
public class BusinessObject{
public Guid Create(Product product){
Create(product, true, true);
}
// internal because all business objects are located in the same assembly
internal Guid Create(Product product, bool performLogging, bool performPermissionCheck){
//perform permission check if required
//perform logging if required
//call data layer to create object
}
}
It is ok. It works but it is going to get me into a lot of overloads. Is this the best solution I throught af using TLS (Thread local storage). But that would be unsafe (the UI guy might know what to set on the thread) and it would be hard to configure what to call (Do permission check do logging etc).
Is the solution I have described above the best solution Anyone else have a better solution for this problem
It is possible to some how find out that the call originated from the same assembly Using reflection or something

Detecting internal calls in business object without using TLS or overloaded internal method
Terry Smith
That is why I mentioned the dynamic proxy in the post above you can have the effect of aspects by wrpping calls to your object via a proxy
Another option in .NET is to inherit from ContextBoundObjects (actually MarshalByRef) - .Net builds transparent proxies and you can weave your own code between the proxy and the real object -
Lastly there are few AOP implementations in .NET (e.g. http://www.castleproject.org/index.php/AspectSharp (which builds on the Dynamic Proxy I mentioned) , http://www.rapier-loom.net/ , http://www.postsharp.org/ and http://dotspect.tigris.org/ )
Arnon
tenchyz
Hello Rodrigo
Thanks for a great answer to my post. Super.
I was actually looking for something like what you made an example of. But I'm very intrigued about the facade idea. (I want to do it the right way :)
Is a facade used for security only, and mayby logging I'm gueessing that it would be "Illigal" to put any kind of logic in the facade.
So something like this would be a good idea
public class ProductBusinessObjectFacade(){
public Guid Create(Product product){
// do permission check
// do logging
return ProductBusinessObject(product);
}
}
public class ProductBusinessObject(){
public Guid Create(){
}
}
And then maybe put the facade objects in a different assembly and use code access security to ensure that the business objects are only called through the facade . Like suggested in the post by Diego Dagum.
Is this the correct way to do it
Duane Haas
siteadm:
here you can find some useful information regarding design patterns:
http://www.dofactory.com/Patterns/PatternFacade.aspx
There you can find an example on how to implement it. Please let me know if you need more help on that.
Rgds
Rodrigo
RBowden
If you are considering the idea of a facade - you may want to look at the Castle's project Dynamic Proxy (see explanation in http://www.codeproject.com/csharp/hamiltondynamicproxy.asp)
Arnon
kawing0510
I had, not exactly the same problem, but very similar
I need to check input parameters for business methods in order to filter SQL injection, cross-scripting and some other kind of attacks but just when passing from the presentation tier to the business tier, not -for performance reasons, once inside the business tier
As someone suggested in this thread, I put validation routines in a business tier facade in order that execution could pass from presentation to business just through this facade. But... how to guarantee that always the facade was going to be applied How to prevent direct calls to the methods I needed to protect from attacks
Code-Access Security (CAS) was the answer, because CAS permits you to narrow which assemblies can call a given assembly, class or method by using strong names
Thus, you can configure your application in a way that the methods you need to protect require a given token (usually the public key, needed to decrypt strong named assemblies). Finally you have to sign every allowed-to-call assembly with the private key. Of course presentation tier assemblies aren't signed, in a way that if they attempt to call business methods directly (not through the facade) they will receive a rude SecurityException from the .NET Framework
About Code Access Security, more info here
clint 2
siteadm, as Arnon said.... you can use either a specific AOP framework or you can create your own implementation using ContextBoundObjects and custom attributes..... I have used the later with good results for caching and auditing/instrumentation so I can provide you with more examples... but to have an idea you would have something like:
[Log("Some log source")]
[Security("Some parameter")]
public void MyBusinessMethod()
{
\\\ some logic here...
}
Using ContextBoundObjects you can inject some code (aspect) before the actual method runs and you can decide what to do for that method based on the information provided by the custom attributes.... for example you can abort the execution and throw an exception if the user has no permission to run this method..... or you can just log or cache the method results......
Another example of this are COM+ componets.... if you see the ServicedComponent class inherits from ContextBoundObject and provides attribute-based functionality too.
Hope it helps
Rgds
Rodrigo
Idanle
Karthik Juneni
Well, if you want to know who's calling any given method... you can use StackTrace and StackFrames classes (System.Diagnostics) ..... you can find out the method, class, type and assembly from where a method was called.... here you have an example:
public string GetCaller()
There I'm returning caller's class and method name.... but it's easy to change it to determine the assembly or whatever (pls. let me know if you need more help on that).{
StackTrace tr = new StackTrace();
StackFrame frame = tr.GetFrame(1);
string callerClass = frame.GetMethod().DeclaringType.ToString();
string callerMethod = frame.GetMethod().Name;
return callerClass + " @ " + callerMethod;
}
Now, if you want to know whether this approach is correct to check for example security.... I would have to say no.... usually, business components are likely to be exposed to the other layers using a facade component or a service interface..... security should be checked at this level instead of checking it on every business component..... well, this is a long story... that you may not want to hear now.... hope it helps.
Rgds
Rodrigo
ivarsv
Siteadm..... security, logging, instrumentation, caching and so on are sometimes called "aspects" in the "aspect oriented programming" (aop) world.
Maybe you can find aop the approach for what you want to implement.... it is the idea at least.
Also you may want to check the Visitor design pattern in the link I've provided to you.
Rgds
Rodrigo
MShetty
Hi Arulvel. Thank you for replying to my post.
So what you are saying is that you would expose a property on the business object (I'm guessing internal) to configure what not to perform inside the methods that I'm calling
Like this
public class BusinessObject{
internal bool SkipLogging
internal bool SkipPermissionCheck
public Guid Create(Product product){
//perform permission check if required
//perform logging if required
//call data layer to create object
}
}
dariodario
Hi Diego
Thanks for a great answer to my post. After reading your post and the post from Rodrigo (rfreire) I'm now thinking of using a facade and code access security.
I'll go read some more up on code access security.
Thank you very much.
nattylife
Hi Rodrigo
Thank you again for posting.
I have read an article about AOP but as I understand it requires that you use a compiler which support AOP so it can inject code into classes. That would me I could not use the compiler from Microsoft. I don't know if that migth present problems
Can you do AOP wihtout this
Thank you I will look at the Visitor pattern
bsh17
Hello Rodrigo
I read up on the Facade pattern I can see that what I made an example was not a facade because I indicated that I wanted make on object in front of each business object.
Actually this is what I want. I don't have the need of a facade. But I can see that it makes a lot of sense make a logical layer in front of the business layer. I would then move permission checking, logging etc. to this logical layer.
Is there a name for such a layer
Thank you for posting the link. Great site.