Authorization question, w/ "Windows" authentication mode

M

matt

hello,

im familar w/ *forms* based authentication, and i have coded several
public-facing web sites that authenticate w/ a forms-based login page;
then get back an array of user roles, and from global.asax.cs's
Application_AuthenticateRequest() assign the roles to the
Security.Principal user.

now i am working on a *windows* based authentication webapp for an
intranet. all users use the windows network to login, and then they
bring up my webapp.

ive set up IIS & web.config, so i have no trouble grabbing their
User.Identity.Name (their windows login). cool. and since i am able to
use global.asax.cs's Application_AuthenticateRequest() i can retrieve
their db-stored roles assign it to the Security.Principal user. cool.


the problem? "Application_AuthenticateRequest()" gets called on every
single page request, which means a hit to the database to get the
user's roles every single pageload. is this normal? (i cant remember if
thats how my prior forms-based webapps worked, too..) if it is normal,
what is the best practice -- deal w/ it? use the Session to cache the
user's roles?


here is my code:

protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (Request.IsAuthenticated)
{
System.Web.HttpContext context = System.Web.HttpContext.Current;

string userName = context.User.Identity.Name; //format:
DOMAIN\user.name

//populate my app-user (gets roles from database)
AppUser myUser = AppUser(userName);

//assign its roles to security model
context.User = new
System.Security.Principal.GenericPrincipal(User.Identity,
myUser.Roles);
}
}


thanks!
matt
 
J

Joe Kaplan \(MVP - ADSI\)

Yes, that is normal. To avoid a database hit, you can use the cache or use
session state or perhaps a cookie (if it is properly MACed or encrypted to
prevent tampering).

Forms auth works the same way. The roles are typically stored in a cookie.

Joe K.
 
M

matt

Joe said:
Yes, that is normal. To avoid a database hit, you can use the cache or use
session state or perhaps a cookie (if it is properly MACed or encrypted to
prevent tampering).

thanks, joe. ill likely store them in the session or a cookie. i did a
quick google on MAC -- is this message authority checking? an article
(non-.NET) mentioned an MD5 algorythm.. know of any nifty .NET code for
this?


thanks!
matt
 
M

matt

Joe said:
To avoid a database hit, you can use the cache or use
session state or perhaps a cookie

actually, i think the options may be limited to the Cache or a cookie.
it appears the Session object doesnt yet exist "Session_Start()" is
executed *after* "Application_AuthenticateRequest()".

i had thought perhap i could just check for Session being null, if so
grab from db, and that after page hit-one Session should then exist.
but...it doesnt. dah!

so it looks like Cache or cookie are the only options. if i did Cache i
supposed id use a unique key based off the userID, w/ a short
time-to-live.


matt
 
D

Dominick Baier [DevelopMentor]

Hi,

session is not available in Post/AuthenticateRequest - i would use the cache
or a cookie

cache has the advantage of being self managed and server only
if cookie i would use the userData field of the FormsAuth ticket - this gives
you encryption and integrity protection + renewal for free

In both cases (a little easier with the cache) - you should periodically
check if the user is still valid and the group memberships are still OK -
otherwise you end up with stale information - especially if sliding expiration
is used.
 
J

Joe Kaplan \(MVP - ADSI\)

I agree with D. You are really implementing a performance optimization
here, so cache is the most appropriate storage to use.

Joe K.
 
J

Joe Kaplan \(MVP - ADSI\)

That's exactly right. Essentially, things like cookies and query strings
need to be treated as input. If you want to ensure that they have not been
tampered with, then you typically want to encrypt (which doesn't ensure
tamper resistance, but it make it difficult for a hacker without the key to
create valid data that has been altered) and/or use signatures/MACs (which
do provide tamper resistance, but do not provide privacy of the data).

The System.Security.Cryptography namespace includes features for encrypting,
signing and adding MACs. You would probably want to find some samples of
how to use these things rather than figuring out how to code them yourself,
as there are some pitfalls and many developers struggle to implement these
things correctly.

Note that this is not absolutely required, but you can't really consider
your system secure if you are taking input from the user that has not been
properly validated. That is web security 101.

Joe K.
 
M

matt

Joe said:
I agree with D. You are really implementing a performance optimization
here, so cache is the most appropriate storage to use.

cache it is. i wrote it yesterday, w/ a short sliding expiration -- 5
minutes. long enough to spare my db from repeated hits from every
uses's page request, short enough that no user will carry stall roles
for very long.


thanks guys!
matt

http://www.sushi-review.com
http://www.semi-suave.com
 
D

Dominick Baier [DevelopMentor]

i wouldn't use sliding expiration - rather choose a longer timeout and no
sliding exp. - this will guarantee you get fresh info after the timout occured.
Otherwise you could keep possible old info alive forever by repeatedly sending
request to the application.
 
M

matt

except that the keyname for the cached data is based on the unique
userID. since no user will user the application for very long, and the
app has a 20 or 30 minute inactivity timeout, perpetually storing stale
data is not possible.

matt
 
M

matt

Dominick said:
so why use sliding expiration then??

because it seems to be thats what sliding is designed for.

- if i use a normal fixed 20-minute expiration, a user could be
actively paging on the site for a 20-30 minute session, and at some
point the cahce item *will* expire, due to the finite TTL, and the db
will be hit.

- if i use a 5-minute sliding expiration, a user could be actively
paging on the site for a 20-30 minute session, and at *no* point will
the mock-session expire, because they are actively using the cached key
item.

now if they sit on the 20-30 minute session for 5 minutes and dont do
anything, yes, it would hit the db again. this is where the behavior of
my users comes into play and a judgement is made.

....probably a "6 of one, half-a-dozen of another" situation.


matt
 
D

Dominick Baier [DevelopMentor]

fair enough.

my first concern still applies - with sliding you can potentially keep the
information alive forever.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top