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.

Reply via email to