473,441 Members | 1,709 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,441 software developers and data experts.

Using PrincipalPermission on WebMethods with Forms Authentication

Greetings:

I am developing an application that uses an ASP.NET Web Forms
application for its UI and ASP.NET web services for its business tier, and I
am looking for assistance in improving my application security. I want to use
declarative security on my web methods so I can secure them more easily. In
short, I want to secure the web services using the first code snippet below.

Please note that the web method has a custom SOAP header. This header
includes three properties, username, password and client id, and currently
provides the mechanism for securing web service access. Each web method
contains code to check the values from the SOAP header against the
application's security metadata. Because of the nature of the application I
cannot use Active Directory - user's must be validated against a database,
and the client id values determines against what database the user name and
password will be validated. I am hoping to avoid the use of procedural code
and to use the PrincipalPermission attribute on my web methods to restrict
access, like so:

[SoapHeader("authHeader")]
[PrincipalPermission(SecurityAction.Demand, Role = "RoleName")]
public DataSet GetUserDetails(...paramlist...)
{
//...
}

This works great, in that the PrincipalPermission attribute is checking
for the specified role, and denying access to the web method. Sadly, it does
this for all users, even those that are members of the appropriate roles - I
cannot figure out how to actually pass a user's credentials along to the web
method from the ASP.NET web forms client application in a manner so that this
actually works. Based on any number of suggestions online, I've tried this in
my client code, to no avail:

UserAdminWS.UserAdmin wsProxy = new UserAdmin();
wsProxy.AuthenticationHeaderValue = new UserAdminWS.AuthenticationHeader();
wsProxy.PreAuthenticate = true;

wsProxy.AuthenticationHeaderValue.clientID = clientID;
wsProxy.AuthenticationHeaderValue.userName = userName;
wsProxy.AuthenticationHeaderValue.userPassword = userPassword;

System.Net.CredentialCache credCache = new System.Net.CredentialCache();
credCache.Add (new Uri(wsProxy.Url), "Basic", new
System.Net.NetworkCredential(wsProxy.Authenticatio nHeaderValue.userName,
wsProxy.AuthenticationHeaderValue.userPassword,
wsProxy.AuthenticationHeaderValue.clientID));

wsProxy.Credentials = credCache;

As far as I can tell, this should work, or at least should be a big part
of the solution, but when I interrogate
HttpContext.Current.User.Identity.Name it always contains the empty string,
and HttpContext.Current.User.Identity.IsAuthenticated is always false. WTF?

I have also tried using the sample code from
http://www.rassoc.com/gregr/weblog/s...Directory.html
and
http://www.rassoc.com/gregr/weblog/s...Directory.html,
but neither one supports passing a third value along with the user name and
password, and without the ability to use the client id any solution is
useless to me.

I'm sure I'm missing something painfully simple, but can't guess what
that might be. Any thoughts or suggestions would be greatly appreciated.
Thanks in advance!

Matthew Roche

Nov 21 '05 #1
4 14528
Hi Matthew,

Are you setting the current user identity in the web service? To do this,
you need to create a Principal object and assign it to the
System.Threading.Thread.CurrentPrincipal property after successful
authentication.

Moreover, I think it is unnecessary to pass the credentials through both a
SoapHeader and proxy.Credentials. If you want to use the SoapHeader, then
write a SoapExtension to examine the header, check the credentials and upon
successful authentication, set the current user identity. Alternatively, if
you want to use HTTP Basic or Digest authentication, pass the credentials in
proxy.Credentials, validate the credentials in the HttpModule (similarly to
Reinacker's sample) and set the current user identity. With one of these in
place, you should be able to use declarative security with the
PrincipalPermission attribute.

Regards,
Sami

"Matthew Roche" <fi****************************@online.nospam> wrote in
message news:F5**********************************@microsof t.com...
Greetings:

I am developing an application that uses an ASP.NET Web Forms
application for its UI and ASP.NET web services for its business tier, and
I
am looking for assistance in improving my application security. I want to
use
declarative security on my web methods so I can secure them more easily.
In
short, I want to secure the web services using the first code snippet
below.

Please note that the web method has a custom SOAP header. This header
includes three properties, username, password and client id, and currently
provides the mechanism for securing web service access. Each web method
contains code to check the values from the SOAP header against the
application's security metadata. Because of the nature of the application
I
cannot use Active Directory - user's must be validated against a database,
and the client id values determines against what database the user name
and
password will be validated. I am hoping to avoid the use of procedural
code
and to use the PrincipalPermission attribute on my web methods to restrict
access, like so:

[SoapHeader("authHeader")]
[PrincipalPermission(SecurityAction.Demand, Role = "RoleName")]
public DataSet GetUserDetails(...paramlist...)
{
//...
}

This works great, in that the PrincipalPermission attribute is checking
for the specified role, and denying access to the web method. Sadly, it
does
this for all users, even those that are members of the appropriate roles -
I
cannot figure out how to actually pass a user's credentials along to the
web
method from the ASP.NET web forms client application in a manner so that
this
actually works. Based on any number of suggestions online, I've tried this
in
my client code, to no avail:

UserAdminWS.UserAdmin wsProxy = new UserAdmin();
wsProxy.AuthenticationHeaderValue = new
UserAdminWS.AuthenticationHeader();
wsProxy.PreAuthenticate = true;

wsProxy.AuthenticationHeaderValue.clientID = clientID;
wsProxy.AuthenticationHeaderValue.userName = userName;
wsProxy.AuthenticationHeaderValue.userPassword = userPassword;

System.Net.CredentialCache credCache = new System.Net.CredentialCache();
credCache.Add (new Uri(wsProxy.Url), "Basic", new
System.Net.NetworkCredential(wsProxy.Authenticatio nHeaderValue.userName,
wsProxy.AuthenticationHeaderValue.userPassword,
wsProxy.AuthenticationHeaderValue.clientID));

wsProxy.Credentials = credCache;

As far as I can tell, this should work, or at least should be a big
part
of the solution, but when I interrogate
HttpContext.Current.User.Identity.Name it always contains the empty
string,
and HttpContext.Current.User.Identity.IsAuthenticated is always false.
WTF?

I have also tried using the sample code from
http://www.rassoc.com/gregr/weblog/s...Directory.html
and
http://www.rassoc.com/gregr/weblog/s...Directory.html,
but neither one supports passing a third value along with the user name
and
password, and without the ability to use the client id any solution is
useless to me.

I'm sure I'm missing something painfully simple, but can't guess what
that might be. Any thoughts or suggestions would be greatly appreciated.
Thanks in advance!

Matthew Roche


Nov 21 '05 #2
Sami:

Thanks for the reply. I guess I wasn't as clear as I was trying to be in
explaining my context. I'm actually trying to find a way to use either one or
the other method for validating users. The SOAP header is my current working
solution, but I haven't been able to make it work with the
PrincipalPermission attribute. I agree that both techniques are not
necessary, but as I haven't yet been able to get either one to work I wanted
to keep my bases covered.

To answer your question "Are you setting the current user identity in
the web service?" the answer currently is No. I honestly am unsure *where* to
set it. So far my web services work has been pretty straightforward, and I
haven't had cause until now to drill down into this sort of thing. I will
take a look at creating a SoapExtension as you suggested and will post a
reply when I have something to report.

Thanks again!

Matthew

"Sami Vaaraniemi" wrote:
Hi Matthew,

Are you setting the current user identity in the web service? To do this,
you need to create a Principal object and assign it to the
System.Threading.Thread.CurrentPrincipal property after successful
authentication.

Moreover, I think it is unnecessary to pass the credentials through both a
SoapHeader and proxy.Credentials. If you want to use the SoapHeader, then
write a SoapExtension to examine the header, check the credentials and upon
successful authentication, set the current user identity. Alternatively, if
you want to use HTTP Basic or Digest authentication, pass the credentials in
proxy.Credentials, validate the credentials in the HttpModule (similarly to
Reinacker's sample) and set the current user identity. With one of these in
place, you should be able to use declarative security with the
PrincipalPermission attribute.

Regards,
Sami

"Matthew Roche" <fi****************************@online.nospam> wrote in
message news:F5**********************************@microsof t.com...
Greetings:

I am developing an application that uses an ASP.NET Web Forms
application for its UI and ASP.NET web services for its business tier, and
I
am looking for assistance in improving my application security. I want to
use
declarative security on my web methods so I can secure them more easily.
In
short, I want to secure the web services using the first code snippet
below.

Please note that the web method has a custom SOAP header. This header
includes three properties, username, password and client id, and currently
provides the mechanism for securing web service access. Each web method
contains code to check the values from the SOAP header against the
application's security metadata. Because of the nature of the application
I
cannot use Active Directory - user's must be validated against a database,
and the client id values determines against what database the user name
and
password will be validated. I am hoping to avoid the use of procedural
code
and to use the PrincipalPermission attribute on my web methods to restrict
access, like so:

[SoapHeader("authHeader")]
[PrincipalPermission(SecurityAction.Demand, Role = "RoleName")]
public DataSet GetUserDetails(...paramlist...)
{
//...
}

This works great, in that the PrincipalPermission attribute is checking
for the specified role, and denying access to the web method. Sadly, it
does
this for all users, even those that are members of the appropriate roles -
I
cannot figure out how to actually pass a user's credentials along to the
web
method from the ASP.NET web forms client application in a manner so that
this
actually works. Based on any number of suggestions online, I've tried this
in
my client code, to no avail:

UserAdminWS.UserAdmin wsProxy = new UserAdmin();
wsProxy.AuthenticationHeaderValue = new
UserAdminWS.AuthenticationHeader();
wsProxy.PreAuthenticate = true;

wsProxy.AuthenticationHeaderValue.clientID = clientID;
wsProxy.AuthenticationHeaderValue.userName = userName;
wsProxy.AuthenticationHeaderValue.userPassword = userPassword;

System.Net.CredentialCache credCache = new System.Net.CredentialCache();
credCache.Add (new Uri(wsProxy.Url), "Basic", new
System.Net.NetworkCredential(wsProxy.Authenticatio nHeaderValue.userName,
wsProxy.AuthenticationHeaderValue.userPassword,
wsProxy.AuthenticationHeaderValue.clientID));

wsProxy.Credentials = credCache;

As far as I can tell, this should work, or at least should be a big
part
of the solution, but when I interrogate
HttpContext.Current.User.Identity.Name it always contains the empty
string,
and HttpContext.Current.User.Identity.IsAuthenticated is always false.
WTF?

I have also tried using the sample code from
http://www.rassoc.com/gregr/weblog/s...Directory.html
and
http://www.rassoc.com/gregr/weblog/s...Directory.html,
but neither one supports passing a third value along with the user name
and
password, and without the ability to use the client id any solution is
useless to me.

I'm sure I'm missing something painfully simple, but can't guess what
that might be. Any thoughts or suggestions would be greatly appreciated.
Thanks in advance!

Matthew Roche


Nov 21 '05 #3
Sami:

Yes, that did the trick. Here's what I did:

1) I created a custom SoapExtension class that calls into my application
database to validate the user's credentials using the values from the SOAP
header and build GenericIdentity and GenericPrincipal and assign the
principal to the current HTTP context and the current thread (the thread
hookup was necessary for the PrincipalPermission attribute to work - setting
the context identity was not sufficient)
2) I created a custom SoapExtensionAttribute class with which to tie the
SoapExtension to the web methods I needed to secure
3) I tagged each web method with the custom SoapExtensionAttribute and
the PrincipalPermission attribute

And now everything works. Thanks for your help!

Matthew

"Sami Vaaraniemi" wrote:
Hi Matthew,

Are you setting the current user identity in the web service? To do this,
you need to create a Principal object and assign it to the
System.Threading.Thread.CurrentPrincipal property after successful
authentication.

Moreover, I think it is unnecessary to pass the credentials through both a
SoapHeader and proxy.Credentials. If you want to use the SoapHeader, then
write a SoapExtension to examine the header, check the credentials and upon
successful authentication, set the current user identity. Alternatively, if
you want to use HTTP Basic or Digest authentication, pass the credentials in
proxy.Credentials, validate the credentials in the HttpModule (similarly to
Reinacker's sample) and set the current user identity. With one of these in
place, you should be able to use declarative security with the
PrincipalPermission attribute.

Regards,
Sami

"Matthew Roche" <fi****************************@online.nospam> wrote in
message news:F5**********************************@microsof t.com...
Greetings:

I am developing an application that uses an ASP.NET Web Forms
application for its UI and ASP.NET web services for its business tier, and
I
am looking for assistance in improving my application security. I want to
use
declarative security on my web methods so I can secure them more easily.
In
short, I want to secure the web services using the first code snippet
below.

Please note that the web method has a custom SOAP header. This header
includes three properties, username, password and client id, and currently
provides the mechanism for securing web service access. Each web method
contains code to check the values from the SOAP header against the
application's security metadata. Because of the nature of the application
I
cannot use Active Directory - user's must be validated against a database,
and the client id values determines against what database the user name
and
password will be validated. I am hoping to avoid the use of procedural
code
and to use the PrincipalPermission attribute on my web methods to restrict
access, like so:

[SoapHeader("authHeader")]
[PrincipalPermission(SecurityAction.Demand, Role = "RoleName")]
public DataSet GetUserDetails(...paramlist...)
{
//...
}

This works great, in that the PrincipalPermission attribute is checking
for the specified role, and denying access to the web method. Sadly, it
does
this for all users, even those that are members of the appropriate roles -
I
cannot figure out how to actually pass a user's credentials along to the
web
method from the ASP.NET web forms client application in a manner so that
this
actually works. Based on any number of suggestions online, I've tried this
in
my client code, to no avail:

UserAdminWS.UserAdmin wsProxy = new UserAdmin();
wsProxy.AuthenticationHeaderValue = new
UserAdminWS.AuthenticationHeader();
wsProxy.PreAuthenticate = true;

wsProxy.AuthenticationHeaderValue.clientID = clientID;
wsProxy.AuthenticationHeaderValue.userName = userName;
wsProxy.AuthenticationHeaderValue.userPassword = userPassword;

System.Net.CredentialCache credCache = new System.Net.CredentialCache();
credCache.Add (new Uri(wsProxy.Url), "Basic", new
System.Net.NetworkCredential(wsProxy.Authenticatio nHeaderValue.userName,
wsProxy.AuthenticationHeaderValue.userPassword,
wsProxy.AuthenticationHeaderValue.clientID));

wsProxy.Credentials = credCache;

As far as I can tell, this should work, or at least should be a big
part
of the solution, but when I interrogate
HttpContext.Current.User.Identity.Name it always contains the empty
string,
and HttpContext.Current.User.Identity.IsAuthenticated is always false.
WTF?

I have also tried using the sample code from
http://www.rassoc.com/gregr/weblog/s...Directory.html
and
http://www.rassoc.com/gregr/weblog/s...Directory.html,
but neither one supports passing a third value along with the user name
and
password, and without the ability to use the client id any solution is
useless to me.

I'm sure I'm missing something painfully simple, but can't guess what
that might be. Any thoughts or suggestions would be greatly appreciated.
Thanks in advance!

Matthew Roche


Nov 21 '05 #4

"Matthew Roche" <fi****************************@online.nospam> wrote in
message news:6E**********************************@microsof t.com...
Sami:

Yes, that did the trick. Here's what I did:

1) I created a custom SoapExtension class that calls into my
application
database to validate the user's credentials using the values from the SOAP
header and build GenericIdentity and GenericPrincipal and assign the
principal to the current HTTP context and the current thread (the thread
hookup was necessary for the PrincipalPermission attribute to work -
setting
the context identity was not sufficient)
2) I created a custom SoapExtensionAttribute class with which to tie
the
SoapExtension to the web methods I needed to secure
3) I tagged each web method with the custom SoapExtensionAttribute and
the PrincipalPermission attribute

And now everything works. Thanks for your help!


This was exactly what I meant, glad you figured it out. Note that you can
also attach the SoapExtension attribute to the web service class. This is
convenient if you want the extension to apply to all web methods.

Regards,
Sami

Nov 21 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Billy Jacobs | last post by:
I have a website which has both secure and non-secure pages. I want to uses forms authentication. How do I accomplish this? Originally I had my web.config file in the root with Forms...
2
by: Showjumper | last post by:
Can i use roles with forms authentication. Once source (book) seems to indicate that it works for Windows auth. while another indicates it can also work with Forms Auth.
1
by: TK | last post by:
What's the best way to implement roll-base access control with forms authentication? I have a IIS6+ASP.NET server which hosts some ASP.NET web applications as separated path that's like...
2
by: MALBANESE | last post by:
I am having trouble using TRACE.AXD to debug my project whan I have Forms Authentication configured. When I try to load the Trace application i am taken to the login page. After I log in I get an...
3
by: branton ellerbee | last post by:
How do you implement a login control across multiple .aspx pages that allows access to pages and directories with the application you are designing? For example, imagine a login control that is...
0
by: William F. Zachmann | last post by:
A web site that will run on Windows Server 2003 and IIS 6.0 needs to provide three levels of access, one for the public and two others for two levels of subscribers. This is a port of a prior site...
18
by: Rippo | last post by:
Hi I am using role base forms authentication in asp.net and have come across a problem that I would like advice on. On a successful login a session variable is set to identify a user. This is...
3
by: Harold Crump | last post by:
Greetings, I need to implement GenericPrincipal based authentication without using ASP.NET Forms Authentication. I know it is much simpler using Forms Authentication, but in this case, I have...
1
by: ABC | last post by:
I have a new project which is a web site used by Internal and External users (login required users) and public users (no login required users). On internal users, all users login network using...
0
by: walterb | last post by:
Hi, I’m using FormsAuthentication and setting a cookie to ensure that each page the user tries to access has the proper security level. All is working well, except the images / graphics are not...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.