web.config, roles and multiple directories

M

Matthias S.

Hi,

here is what I'm trying to do: I have a virtual directory called
"WebApp". Under this one I've got 2 physical directories called
"Customers" and "Admins".

I implemented Forms-based authentication. If the logon credentials are
ok, I transfer the user to either the "Customers" or the "Admins"
subdirectory. Those two directories should have a web.config file, which
allows the roles "Admins" and "Customers" access the resources in the
directories.

But I can't figure out how to set the Role when I create the Ticket for
the guy logging on during authentification.

Can anybody help me out?

Thanks in advance...

Matthias
 
B

Brock Allen

You don't set roles at authentication time... I know, it's a bit strange.
Instead you typically set the roles in global.asax in the Application_AuthenticateRequest
event as such:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
if (User.Identity.Name == "brock")
{
string[] roles = new string[2];
roles[0] = "Admin";
roles[1] = "Doctor";

Context.User =
new System.Security.Principal.GenericPrincipal(User.Identity,
roles);
}
}
}

This is hard coded for a specific name, so you'd normally go look this up
in the DB based upon User.Identity.Name. One note: this is called for every
request into your application, so going to the DB every time is going to
be expensive. I'd suggest caching the roles (probabaly in the ASP.NET Cache
object).
 
J

Jason Bentley

Matthias, is there a reason you are using three different web.config
files? You could do it all in one. You can deny access to each of the
Customers or Admins directories and redirect them based on their acces
role.

Jason Bentley
http://geekswithblogs.net/jbentley
 
M

Matthias S.

Hi Brock,

thanks for your reply. In the meantime I've been looking for a different
solution and found something, but I'm not sure whether this is secure:

I only have a couple of pages in those subdirectories. So I would go for
setting my role-identifier as the UserData in the
FormsAuthenticationTicket when I authenticate the user. Later I'd go and
check (on each and every page) whether the user belongs to the role that
can actually access the specified page.

If I encrypt the ticket, would it be safe to store the role in the UserData?

Again, thanks for your help.

Matthias

Brock said:
You don't set roles at authentication time... I know, it's a bit
strange. Instead you typically set the roles in global.asax in the
Application_AuthenticateRequest event as such:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
if (User.Identity.Name == "brock")
{
string[] roles = new string[2];
roles[0] = "Admin";
roles[1] = "Doctor";

Context.User =
new
System.Security.Principal.GenericPrincipal(User.Identity, roles);
}
}
}

This is hard coded for a specific name, so you'd normally go look this
up in the DB based upon User.Identity.Name. One note: this is called for
every request into your application, so going to the DB every time is
going to be expensive. I'd suggest caching the roles (probabaly in the
ASP.NET Cache object).




Hi,

here is what I'm trying to do: I have a virtual directory called
"WebApp". Under this one I've got 2 physical directories called
"Customers" and "Admins".

I implemented Forms-based authentication. If the logon credentials are
ok, I transfer the user to either the "Customers" or the "Admins"
subdirectory. Those two directories should have a web.config file,
which allows the roles "Admins" and "Customers" access the resources
in the directories.

But I can't figure out how to set the Role when I create the Ticket
for the guy logging on during authentification.

Can anybody help me out?

Thanks in advance...

Matthias
 
B

Brock Allen

Yes of course you could take this approach too. You'd still need to handle
Application_AuthenticateRequest to read the data from the cookie and then
construct the GenericPrincipal and assign it into the HttpContext.Current.User.




Hi Brock,

thanks for your reply. In the meantime I've been looking for a
different solution and found something, but I'm not sure whether this
is secure:

I only have a couple of pages in those subdirectories. So I would go
for setting my role-identifier as the UserData in the
FormsAuthenticationTicket when I authenticate the user. Later I'd go
and check (on each and every page) whether the user belongs to the
role that can actually access the specified page.

If I encrypt the ticket, would it be safe to store the role in the
UserData?

Again, thanks for your help.

Matthias

Brock said:
You don't set roles at authentication time... I know, it's a bit
strange. Instead you typically set the roles in global.asax in the
Application_AuthenticateRequest event as such:

protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (Request.IsAuthenticated)
{
if (User.Identity.Name == "brock")
{
string[] roles = new string[2];
roles[0] = "Admin";
roles[1] = "Doctor";
Context.User =
new
System.Security.Principal.GenericPrincipal(User.Identity, roles);
}
}
}
This is hard coded for a specific name, so you'd normally go look
this up in the DB based upon User.Identity.Name. One note: this is
called for every request into your application, so going to the DB
every time is going to be expensive. I'd suggest caching the roles
(probabaly in the ASP.NET Cache object).

Hi,

here is what I'm trying to do: I have a virtual directory called
"WebApp". Under this one I've got 2 physical directories called
"Customers" and "Admins".

I implemented Forms-based authentication. If the logon credentials
are ok, I transfer the user to either the "Customers" or the
"Admins" subdirectory. Those two directories should have a
web.config file, which allows the roles "Admins" and "Customers"
access the resources in the directories.

But I can't figure out how to set the Role when I create the Ticket
for the guy logging on during authentification.

Can anybody help me out?

Thanks in advance...

Matthias
 
M

Matthias S.

Hi Brock,

I don't understand, why I would need to handle the
Application_AuthenticateRequest. Is it not sufficient to just have code
like this in the Page_Load event of every page in the subdirectories:

I assume the RoleID is a numeric value and has been placed in the
Tickets UserData property.

+++
FormsIdentity identity = (FormsIdentity) Page.User.Identity;

if(identity.IsAuthenticated) {
int nRoleID = int.Parse(identity.Ticket.UserData);
if (nRoleID == 1) {
// the user is an admin
}
else {
// authenticated, but not an admin
}
}
else {
// not authenticated...
}
+++

I've played around with it and it seems to work. Sorry for buzzering but
I'd just like to get this straight for me.

Again, thanks for your help!

Matthias

Brock said:
Yes of course you could take this approach too. You'd still need to
handle Application_AuthenticateRequest to read the data from the cookie
and then construct the GenericPrincipal and assign it into the
HttpContext.Current.User.




Hi Brock,

thanks for your reply. In the meantime I've been looking for a
different solution and found something, but I'm not sure whether this
is secure:

I only have a couple of pages in those subdirectories. So I would go
for setting my role-identifier as the UserData in the
FormsAuthenticationTicket when I authenticate the user. Later I'd go
and check (on each and every page) whether the user belongs to the
role that can actually access the specified page.

If I encrypt the ticket, would it be safe to store the role in the
UserData?

Again, thanks for your help.

Matthias

Brock said:
You don't set roles at authentication time... I know, it's a bit
strange. Instead you typically set the roles in global.asax in the
Application_AuthenticateRequest event as such:

protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (Request.IsAuthenticated)
{
if (User.Identity.Name == "brock")
{
string[] roles = new string[2];
roles[0] = "Admin";
roles[1] = "Doctor";
Context.User =
new
System.Security.Principal.GenericPrincipal(User.Identity, roles);
}
}
}
This is hard coded for a specific name, so you'd normally go look
this up in the DB based upon User.Identity.Name. One note: this is
called for every request into your application, so going to the DB
every time is going to be expensive. I'd suggest caching the roles
(probabaly in the ASP.NET Cache object).



Hi,

here is what I'm trying to do: I have a virtual directory called
"WebApp". Under this one I've got 2 physical directories called
"Customers" and "Admins".

I implemented Forms-based authentication. If the logon credentials
are ok, I transfer the user to either the "Customers" or the
"Admins" subdirectory. Those two directories should have a
web.config file, which allows the roles "Admins" and "Customers"
access the resources in the directories.

But I can't figure out how to set the Role when I create the Ticket
for the guy logging on during authentification.

Can anybody help me out?

Thanks in advance...

Matthias
 
B

Brock Allen

The main reason is that you're missing out on the declarative authorization
in web.config. In web.config you can put:

<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>

The huge win here is that you *don't* have to check in each page. It's checked
for you based upon your declarative settings. This is what I was referring
to before when I said you don't have to do all of this work yourself. But,
to make the built-in check work for you, you need to build the role list
in a GenericPrincipal and assign it to the HttpContext.Current.User in Application_AuthenticateRequest.




Hi Brock,

I don't understand, why I would need to handle the
Application_AuthenticateRequest. Is it not sufficient to just have
code like this in the Page_Load event of every page in the
subdirectories:

I assume the RoleID is a numeric value and has been placed in the
Tickets UserData property.

+++
FormsIdentity identity = (FormsIdentity) Page.User.Identity;
if(identity.IsAuthenticated) {
int nRoleID = int.Parse(identity.Ticket.UserData);
if (nRoleID == 1) {
// the user is an admin
}
else {
// authenticated, but not an admin
}
}
else {
// not authenticated...
}
+++

I've played around with it and it seems to work. Sorry for buzzering
but I'd just like to get this straight for me.

Again, thanks for your help!

Matthias

Brock said:
Yes of course you could take this approach too. You'd still need to
handle Application_AuthenticateRequest to read the data from the
cookie and then construct the GenericPrincipal and assign it into the
HttpContext.Current.User.

Hi Brock,

thanks for your reply. In the meantime I've been looking for a
different solution and found something, but I'm not sure whether
this is secure:

I only have a couple of pages in those subdirectories. So I would go
for setting my role-identifier as the UserData in the
FormsAuthenticationTicket when I authenticate the user. Later I'd go
and check (on each and every page) whether the user belongs to the
role that can actually access the specified page.

If I encrypt the ticket, would it be safe to store the role in the
UserData?

Again, thanks for your help.

Matthias

Brock Allen wrote:

You don't set roles at authentication time... I know, it's a bit
strange. Instead you typically set the roles in global.asax in the
Application_AuthenticateRequest event as such:

protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (Request.IsAuthenticated)
{
if (User.Identity.Name == "brock")
{
string[] roles = new string[2];
roles[0] = "Admin";
roles[1] = "Doctor";
Context.User =
new
System.Security.Principal.GenericPrincipal(User.Identity, roles);
}
}
}
This is hard coded for a specific name, so you'd normally go look
this up in the DB based upon User.Identity.Name. One note: this is
called for every request into your application, so going to the DB
every time is going to be expensive. I'd suggest caching the roles
(probabaly in the ASP.NET Cache object).

Hi,

here is what I'm trying to do: I have a virtual directory called
"WebApp". Under this one I've got 2 physical directories called
"Customers" and "Admins".

I implemented Forms-based authentication. If the logon credentials
are ok, I transfer the user to either the "Customers" or the
"Admins" subdirectory. Those two directories should have a
web.config file, which allows the roles "Admins" and "Customers"
access the resources in the directories.

But I can't figure out how to set the Role when I create the
Ticket for the guy logging on during authentification.

Can anybody help me out?

Thanks in advance...

Matthias
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top