.NET Forum / Languages / C# / November 2006
Internal access modifier is not working the way I thought it would.
|
|
Thread rating:  |
JT - 03 Nov 2006 13:30 GMT Here is the overall structure I will be referring to: End-program ProvideWorkFlow.dll Forms and methods that properly manipulate calls to methods in AccessUtils AccessUtils (a web service) Hide.dll methods and data I want to remain hidden
I have a DLL, Hide.dll, that contains methods that I want to handle for end-programmers. The methods in Hide.dll are declared as public. I have a web service, AccessUtils, that provides access to these methods by acting as a "go-between". It uses identical method signatures and just returns the result of the method calls in the DLL. The WebMethods are declared as public.
Example: [WebMethod] public string GetSensitiveInfo(string pKeyValue) { Hide.Utils HiddenUtils = new Hide.Utils(); return HiddenUtils.GetSensitiveInfo(pKeyValue); } // end of GetSensitiveInfo()
Furthermore, there are programmers that need this functionality but don't need, and shouldn't have, direct access to the methods in Hide.dll, or even directly use the methods in the AccessUtils web service. I have a DLL, ProvideWorkFlow.dll, that contains public Windows Forms and methods that will make the appropriate calls to the AccessUtils web service in the appropriate order and thereby enforce the "work flow", although I'm not sure I would call it a true work flow model. In ProvideWorkFlow.dll, I declare AccessUtils as an "internal" to try to make its methods available only inside this ProvideWorkFlow.dll assembly. However, if I act as a programmer that would be using ProvideWorkFlow.dll, when I go to instantiate one of its forms, I see that the forms are available, but also the namespace for the AccessUtils web service is available to be instantiated. I tried declaring AccessUtils as private in ProvideWorkFlow.dll but it was still visible and available. I thought the whole purpose of declaring something as internal was to prevent it from being visible outside the containing DLL (assembly).
How do I need to set this up so that the end programmer only has access to the forms and methods declared in ProvideWorkFlow.dll?
Dave Sexton - 03 Nov 2006 15:36 GMT Hi,
You are correct that object definitions and members defined with the internal modifier will only be visible to the assembly in which they are defined.
If you are able to construct internal classes or call internal methods then I assume you are doing so from the same assembly. (BTW, namespaces cannot be instantiated)
Your best option would probably be to build all of it into the ProvideWorkFlow.dll, since that is the public interface, making objects and methods private or internal as needed.
 Signature Dave Sexton
> Here is the overall structure I will be referring to: > End-program [quoted text clipped - 40 lines] > How do I need to set this up so that the end programmer only has access > to the forms and methods declared in ProvideWorkFlow.dll? JT - 03 Nov 2006 17:51 GMT Thanks Dave,
Actually, I mis-spoke. The classes within the web service's namespace (AccessUtils) are able to be instantiated from within the end program. Below I am going to indicate Intellisense options text between pound signs, #. Also, AccessUtilities will represent the class defined within the AccessUtils web service. So for instance, if I have a reference to ProvideWorkFlow.dll and then, in the program, I begin to instantiate methods and forms from ProvideWorkFlow, I will see something like the following:
ProvideWorkFlow.InitialContactForm frmInitContact = new ProvideWorkFlow.InitialContactForm();
ProvideWorkFlow. # InitialContactForm CustomerFeedbackForm CustomerProcessingMethods {} AccessUtils <-- web service namespace FollowUpForm #
ProvideWorkFlow.AccessUtils. # AccessUtilities <-- class containing WebMethods AssignCustomerToAgentEventArgs AssignCustomerToAgentEventHandler StartProcessingCustomerEventArgs StartProcessingCustomerEventHandler ... #
ProvideWorkFlow.AccessUtils.AccessUtilities auMethods = new ProvideWorkFlow.AccessUtils.AccessUtilities();
auMethods.AssignCustomerToAgent(CustomerID, AgentID);
In the previous example, it would be completely inappropriate for the programmer to have direct access to the AssignCustomerToAgent() method.
To address your other statement, the reason this needs to reside in a web service is because the database is on a web server that is, well, who really knows where? So that is why the ProvideWorkFlow.dll references and instantiates the AccessUtils.AccessUtilities class. So in ProvideWorkFlow.dll, I make the following declaration:
internal AccesUtils.AccessUtilities auMethods; ... auMethods = new AccesUtils.AccessUtilities();
Then, the methods in ProvideWorkFlow.dll call the appropriate AccessUtilities methods in a way that won't violate the business rules.
I reallly thought that would do what I needed. Any other suggestions?
Thanks,
JT
> Hi, > [quoted text clipped - 56 lines] > > How do I need to set this up so that the end programmer only has access > > to the forms and methods declared in ProvideWorkFlow.dll? Dave Sexton - 04 Nov 2006 03:53 GMT Hi,
Your example only shows me that you have marked a member variable as internal:
> internal AccesUtils.AccessUtilities auMethods; However, the class definition is not marked internal and that's why it's available to be instantiated externally:
namespace ProvideWorkFlow.AccessUtils { public class AccessUtilities { } }
should be:
namespace ProvideWorkFlow.AccessUtils { internal class AccessUtilities { } }
The problem is that once AccessUtilities is marked as internal it can't be referenced by the ProvideWorkFlow.dll either. That's why I recommended that you include the web service in your ProvideWorkFlow.dll instead of a separate assembly. Then, you can make the web service internal to the ProvideWorkFlow assembly.
If you require AccessUtilities to be located in a separate assembly then the easiest solution is to just keep it public and tell your programmers to use the interface supplied by ProvideWorkFlow.dll classes.
Although, you could use some design pattern to hide the implementation behind an abstract factory and an interface so that programmers would be more inclined to use the interface provided by ProvideWorkFlow.dll instead of creating their own; however, they would be able to implement their own and directly access the web service if they really wanted.
To be perfectly honest, I don't think it's a good idea to try and shield your programmers from using the wrong tools, but instead educate them to use the right ones. I highly recommend fostering open communication. Pair programming, peer review and unit testing can help to shine a light on "strays". So don't take the latter choice lightly - use at your own risk!
 Signature Dave Sexton
> Thanks Dave, > [quoted text clipped - 118 lines] >> > How do I need to set this up so that the end programmer only has access >> > to the forms and methods declared in ProvideWorkFlow.dll? JT - 06 Nov 2006 20:10 GMT Hey Dave,
Here's my problem. The programmers I'm referring to, I have never met, may never meet, and may pass on the DLL to people I didn't expect. The point is to provide this DLL to anyone and everyone who wants to use it, as long as I can control how they use it. So while I would like to think that it wouldn't end up in the hands of someone who wants to cause harm or does so accidentally, I can't count on that.
I'm confused about what you're suggesting. Maybe there's an aspect I haven't thought of. As far as I know (might not be as far as I think), there is no way to include the web service in the DLL that I want to distribute. It must refer to the web service on its web server and therefore, can't be encapsulated as an additional class in the DLL's namespace. If I'm wrong, then I'll need explicit instructions on how to do that. Yes, I was hoping to make the instantiation of auMethods an internal because I can do that with individual methods within ProvideWorkFlow.dll, but it doesn't seem to honor that request for the web service. For all I know, it may not be just web services, but also instantiated DLLs as well. I haven't tried that yet.
Maybe I'll try marking my class as internal inside the web service, but I am wondering if that will prevent the ProvideWorkFlow DLL from being able to use it.
Tricky stuff. I'll let you know what I find.
JT
> Hi, > [quoted text clipped - 168 lines] > >> > How do I need to set this up so that the end programmer only has access > >> > to the forms and methods declared in ProvideWorkFlow.dll? Bruce Wood - 06 Nov 2006 21:02 GMT There is no such thing as an "internal assembly" in .NET. That is, once you declare something public within a DLL then any program can include that DLL as a reference and use that class / method / field / etc.
Stated another way, the highest level to which access modifiers apply is the assembly. If something is publicly visible outside a DLL assembly then it is publicly available to any code that references that DLL.
> Hey Dave, > [quoted text clipped - 197 lines] > > >> > How do I need to set this up so that the end programmer only has access > > >> > to the forms and methods declared in ProvideWorkFlow.dll? Dave Sexton - 06 Nov 2006 21:38 GMT Hi,
You never mentioned that the web service in "Hide.dll" was the actual web service implementation. I assumed that it was a client web-reference because your question doesn't make sense otherwise.
In that case, the web service certainly must be in another assembly if ProvideWorkFlow.dll will be distributed.
Web services provide public interfaces. Anyone can access them and there is no way to force programmers to use your "ProvideWorkFlow.dll" components, AFAIK, because there is no way to provide a secure authentication scheme between your client components and service components that programmers wouldn't be able to discover and circumvent if they desired.
You cannot mark web methods as internal because that breaks the public contract to which web services must adhere.
 Signature Dave Sexton
> Hey Dave, > [quoted text clipped - 212 lines] >> >> > access >> >> > to the forms and methods declared in ProvideWorkFlow.dll? JT - 07 Nov 2006 01:44 GMT Bruce,
Yes, I see your point, but I have a public DLL, "primary", with a public method, "primary.a", and its class is being instantiated in another public method, "secondary", but it's being instantiated inside an internal method, "secondary.MyInternal". An application that is referencing the secondary.dll is not able to see primary.dll, which is what I would want.
Dave,
Well, actually, Hide.dll is referenced by the web service. I know we're going back quite a bit, so here's the code again:
> >> >> > Example: > >> >> > [WebMethod] [quoted text clipped - 3 lines] > >> >> > return HiddenUtils.GetSensitiveInfo(pKeyValue); > >> >> > } // end of GetSensitiveInfo() I'm perfectly willing to let the DLL access the web service. I just don't want anyone else to access the web service directly. I think there's a way to hard-code the permissions so that only the DLL can use the web methods. I just would prefer it if they would never see those web methods. I guess that's what I'll have to do (if I can).
If any of you have any new insights, I'd be glad to hear them, but I think the flies are already gathering around this horse.
Thanks to all for your very helpful knowledge.
JT
> Hi, > [quoted text clipped - 233 lines] > >> >> > access > >> >> > to the forms and methods declared in ProvideWorkFlow.dll? Dave Sexton - 07 Nov 2006 02:43 GMT Hi,
Web services provide public interfaces.
AFAIK, there is no way to use CAS permissions such as StrongNameIdentityPermission over SOAP, so I don't think the CLR will be able to enforce that your assembly can be the only client to access the service. The reason for this is simple - SOAP is XML and can be spoofed very easily.
Any authentication / authorization scheme that you design will have to be useable from the ProvideWorkFlow.dll in order for it to access the web service, which means that all of the security information such as encryption algorithms and credentials being used will be perfectly visible to any programmer that has access to the ProvideWorkFlow.dll. No matter the security mechanism that you choose, even with obfuscation, will just be security through obscurity, which isn't really security at all.
You won't be able to prevent programmers from accessing your web service.
Instead of trying to prevent programmers from accessing the web service:
1. Provide programmers with all they need in the ProvideWorkFlow.dll so that they don't go looking for workarounds
2. Carefully architect the web service so that it doesn't expose any functionality that can be misused, just in case programmers become curious
For example, if you require certain methods to be called in a particular order then enforce the order of execution within the web service itself, not ProvideWorkFlow.dll. Web services can support Session information just like an ASP.NET application, which will make things like that much easier since you can store context information per connection.
"Using ASP.NET Session State in a Web Service" http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/ service08062002.asp
3. Educate programmers about your architecture through documentation. Include information about the ProvideWorkFlow.dll assembly and the web service that it requires to run properly. Let programmers know that ProvideWorkFlow.dll provides the only interface that will be useful to them since it acts as the facade over a more complex system that requires a working knowledge of internal implementation details in order to be used properly.
-- Authentication / authorization should be implemented anyway if the web service will be accessible over a public IP address and contains sensitive information, but this will only prevent unsolicited access from those clients that don't have the ProvideWorkFlow.dll. You can't be sure that it will prevent those that have the assembly from figuring out how to directly access the web service from their own projects.
"Securing Xml Web Services created using ASP.NET" http://msdn2.microsoft.com/en-us/library/w67h0dw7(VS.80).aspx
Hide.dll has nothing to do with this, apparently, because you're really just trying to prevent access to your web service. Please correct me if I'm wrong.
HTH
 Signature Dave Sexton
> Bruce, > [quoted text clipped - 292 lines] >> >> >> > access >> >> >> > to the forms and methods declared in ProvideWorkFlow.dll? JT - 09 Nov 2006 11:31 GMT Hi Dave,
As soon as I get the chance, I'll go look through all that. I'm sure there are some very good approaches in those articles. I appreciate alll your help.
JT
> Hi, > [quoted text clipped - 354 lines] > >> >> >> > access > >> >> >> > to the forms and methods declared in ProvideWorkFlow.dll?
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|