Hey all, The short version of my question --------------------------------
Is it safe to use Thread.CurrentPrincipal to set up a user-specific GenericPrincipal from ASP.NET for the purposes of implementing declarative role-based code-access security in my business logic components? The long version of my question --------------------------------- I'm developing an application in ASP.NET which consists of three logical layers of code implemented without a remoting boundary. The setup looks something like this: The ASP.NET presentation code ("src=" code-behind design) handles only presentation processing; for all business logic manipulation it makes a one-line call to my middle layer, which is one class (per app) exposing static business logic coordination services, compiled as a DLL; this essentially puts together a string of business logic that performs some top-level application function. That layer, in turn, makes calls to my application logic components, which actually perform the basic, atomic tasks that the coordinator strings together. The justification for such a setup, and the driving force behind my question, is that the coordinator and application components may get called from a number of different places, some remote and some local. Since a lot of code may be accessing these components, and since I'd like to make sure that security is tight in the system, I want to implement a declarative code-access security mechanism (based on PrincipalPermissionAttribute) around my application components. I've demonstrated that such a thing is possible (and, indeed, pretty simple) in ASP.NET applications, but doing so requires manipulating Thread.CurrentPrincipal; I haven't been able to find a good explanation on exactly how the threading within ASP.NET works, so I don't know if this method is safe for use on an application with concurrent users. To simulate my scenario, build any webform and, in the Page_Load event handler, include the following code: <snippet lang="C#"> // Generate a sample IPrincipal GenericIdentity i = new GenericIdentity("JohnDoe"); GenericPrincipal p = new GenericPrincipal(I,new string[] {"user", "admin"}); // Associate that IPrincipal with the ASP.Net Context Context.User = p; // Now here's the crux: Thread.CurrentPrincipal = p; </snippet> Now define a declaratively-restricted function like this: <snippet> [PrincipalPermissionAttribute(SecurityAction.Demand, Role="admin")] public void secureFun() { // Do nothing here } </snippet> Then, put the following in some event handler: <snippet> secureFun(); </snippet> When you run the page and fire the event handler, it will run just fine, no problem. However, if you comment out just the line 'Thread.CurrentPrincipal = p;', it will fail, since the Context.User principal doesn't affect the CLR's CAS checks. This demonstrates why I need to tangle with the thread's principal, rather than simply the HttpContext's. Since Context.User is the standard way to work with principals in ASP.NET, I'm not sure that what I'm doing is completely safe. ASP.NET employs a thread pool, I understand, and so I need to make sure that this will only set up the IPrincipal object (if defined, say, in FormsAuthentication_OnAuthenticate, for example) for the current ASP.NET user and persist that identification through the business logic processes. Again, I'm not doing any remoting here, though I might in the future; all operations are being done directly, through local libraries, so *within* the app logic all threading should be just like any normal app. It's between requests, which may be concurrent, that I'm concerned. So: anyone have any ideas on this topic? Or, does anyone have any suggestions on alternative methods of accomplishing a similar effect? Feedback is appreciated. Also, if there's any documentation I've missed on the real nitty-gritty of the ASP.NET CLR hosting mechanism and threading issues, those would be helpful as well. Thanks, Dominic Pease You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.