Groups | Blog | Home
all groups > asp.net security > june 2006 >

asp.net security : Authorization question, w/ "Windows" authentication mode


matt NO[at]SPAM mailinator.com
6/28/2006 2:35:21 PM
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
Joe Kaplan (MVP - ADSI)
6/28/2006 4:42:24 PM
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.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
[quoted text, click to view]

matt NO[at]SPAM mailinator.com
6/29/2006 8:01:56 AM

[quoted text, click to view]

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
matt NO[at]SPAM mailinator.com
6/29/2006 8:37:42 AM

[quoted text, click to view]

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
Joe Kaplan (MVP - ADSI)
6/29/2006 12:37:58 PM
I agree with D. You are really implementing a performance optimization
here, so cache is the most appropriate storage to use.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
"Dominick Baier [DevelopMentor]" <dbaier@pleasepleasenospamdevelop.com>
[quoted text, click to view]

Joe Kaplan (MVP - ADSI)
6/29/2006 12:42:17 PM
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.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
[quoted text, click to view]

Dominick Baier [DevelopMentor]
6/29/2006 4:52:26 PM
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.

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com

[quoted text, click to view]

matt NO[at]SPAM mailinator.com
6/30/2006 11:09:42 AM

[quoted text, click to view]

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
Dominick Baier [DevelopMentor]
7/1/2006 5:22:03 PM
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.

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com

[quoted text, click to view]

matt NO[at]SPAM mailinator.com
7/3/2006 2:09:15 PM
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

[quoted text, click to view]
Dominick Baier [DevelopMentor]
7/3/2006 8:15:37 PM
so why use sliding expiration then??

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com

[quoted text, click to view]

matt NO[at]SPAM mailinator.com
7/7/2006 11:07:43 AM

[quoted text, click to view]

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
Dominick Baier [DevelopMentor]
7/7/2006 7:29:13 PM
fair enough.

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

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com

[quoted text, click to view]

AddThis Social Bookmark Button