HTTPWebRequest.request.GetResponse fails: remote server returned error: (401) unauthorized.
am 20.03.2007 19:08:37 von Robert Faulkner
I have an asp.net web application which posts a request to another asp.net web application. I am coding in C# using Visual studio 2003, with .Net Framework 1.1 on a Wiondows 2003 server (running IIS 6.0.). In order to have all code running as managed code, I changed existing code which uses MSXML ServerXMLHTTPClass to post requests to code using the .Net HTTPWebRequest class. When migrating the application to the Test web server, IIS appears to prevent access (=no record of the request in the Windows\System32\Logfiles\W3SVC1 files). I am using impersonation in the web.config file of the client and 'server' web applications. The Application needs to be configured in IIS to 'Windows Authentication' only. The impersonated account is a member of IIS_WPG group an has NTFS permissions to the Applications physical folder. Even if I open up security (allow everyone). There is no web proxy issue. Both client and Server applications are at this point both on the same Test server with the same specs as the development machine (above).
THE ONLY WAY IT FUNCTIONS IS IF IIS FOR THE APPLICATION ON THE SERVER HAS 'ENABLE ANONYMOUS' TICKED.
I see a lot of posts on the internet highlighting this problem without any difinitive answer. Surely, Microsoft wishes the Managed classes to be used. Why then does there appear to be such a hassle for coders to use the class to achieve the same result as the MSXML classes?
The code below is what I am using to make the call. Tracing shows that the call fails when the request is made (GetResponse()).
HttpWebRequest request=null;
Uri uri = new Uri(requestTargetAndQuery);
request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = "GET";
request.Credentials = new NetworkCredential(this.m_User, this.m_Password);
string result=string.Empty;
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
request response.",traceSwitch);
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8))
{ result = readStream.ReadToEnd();
}
}
}
Hopefully someone can point me in the right direction (or let me know if the Framework class does not have the capability to achieve what I am trying)
Thanks Grant_S
From http://developmentnow.com/g/91_0_0_0_0_0/inetserver-iis-secu rity.htm
Posted via DevelopmentNow.com Groups
http://www.developmentnow.com
Re: HTTPWebRequest.request.GetResponse fails: remote server returned error: (401) unauthorized.
am 21.03.2007 02:43:08 von David Wang
If you do not see record of the request in the %windir%
\System32\LogFiles\W3SVC1 files, then either IIS did not handle the
request or the logfile has not flushed yet. It does *not* mean that
"IIS appears to prevent access" because even if IIS prevents access,
it should be logged.
Can you clearly state exactly what you are trying to do -- what user
identity has access to what and where. At this point, you described a
whole bunch of configuration, some of them redundant and others
conflicting, and I don't know what you are trying to accomplish. It is
a recipe for having authentication issues.
What I want to know:
Do you want authenticated user credentials from the client ASP.Net
application to flow to the server ASP.Net application, or do you want
to authenticate the user identity on the front-end but use a different
impersonated identity to reverse-proxy access to the server ASP.Net
application. And what is the configured Application Pool identity
running the client ASP.Net application.
FYI: This "hassle" is a good thing because it reminds the coders that
they may not be as up-to-date on application security and
authentication protocols as they should be. It is important to hassle
coders to get it right because this is the front door and roadmap to
their server's kingdom, and you want it to be sturdy and secure, not
just gaping wide open. Security does not happen "automagically" - it
happens by design.
Personally, I think that if you get a 401, you should think "darn,
what else did I forget" and NOT "darn, why is Microsoft making it a
hassle". The era of running as administrator or LocalSystem to avoid
"access denied" and have things "magically work" is over.
//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//
On Mar 20, 11:08 am, Grant_S wrote:
> I have an asp.net web application which posts a request to another asp.net web application. I am coding in C# using Visual studio 2003, with .Net Framework 1.1 on a Wiondows 2003 server (running IIS 6.0.). In order to have all code running as managed code, I changed existing code which uses MSXML ServerXMLHTTPClass to post requests to code using the .Net HTTPWebRequest class. When migrating the application to the Test web server, IIS appears to prevent access (=no record of the request in the Windows\System32\Logfiles\W3SVC1 files). I am using impersonation in the web.config file of the client and 'server' web applications. The Application needs to be configured in IIS to 'Windows Authentication' only. The impersonated account is a member of IIS_WPG group an has NTFS permissions to the Applications physical folder. Even if I open up security (allow everyone). There is no web proxy issue. Both client and Server applications are at this point both on the same Test server with the same specs as the development machine (above).
>
> THE ONLY WAY IT FUNCTIONS IS IF IIS FOR THE APPLICATION ON THE SERVER HAS 'ENABLE ANONYMOUS' TICKED.
>
> I see a lot of posts on the internet highlighting this problem without any difinitive answer. Surely, Microsoft wishes the Managed classes to be used. Why then does there appear to be such a hassle for coders to use the class to achieve the same result as the MSXML classes?
>
> The code below is what I am using to make the call. Tracing shows that the call fails when the request is made (GetResponse()).
>
> HttpWebRequest request=null;
> Uri uri = new Uri(requestTargetAndQuery);
> request = (HttpWebRequest) WebRequest.Create(uri);
> request.Method = "GET";
> request.Credentials = new NetworkCredential(this.m_User, this.m_Password);
> string result=string.Empty;
> using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
> {
> request response.",traceSwitch);
> using (Stream responseStream = response.GetResponseStream())
> {
> using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8))
> { result = readStream.ReadToEnd();
> }
>
> }
> }
>
> Hopefully someone can point me in the right direction (or let me know if the Framework class does not have the capability to achieve what I am trying)
>
> Thanks Grant_S
>
> Fromhttp://developmentnow.com/g/91_0_0_0_0_0/inetserver-iis- security.htm
>
> Posted via DevelopmentNow.com Groupshttp://www.developmentnow.com
Re: HTTPWebRequest.request.GetResponse fails: remote server returned error: (401) unauthorized.
am 21.03.2007 11:27:02 von Grant_Sutty
On Mar 21, 1:43 am, "David Wang" wrote:
> If you do not see record of the request in the %windir%
> \System32\LogFiles\W3SVC1 files, then either IIS did not handle the
> request or the logfile has not flushed yet. It does *not* mean that
> "IIS appears to prevent access" because even if IIS prevents access,
> it should be logged.
>
> Can you clearly state exactly what you are trying to do -- what user
> identity has access to what and where. At this point, you described a
> whole bunch of configuration, some of them redundant and others
> conflicting, and I don't know what you are trying to accomplish. It is
> a recipe for having authentication issues.
>
> What I want to know:
> Do you want authenticated user credentials from the client ASP.Net
> application to flow to theserverASP.Net application, or do you want
> to authenticate the user identity on the front-end but use a different
> impersonated identity to reverse-proxy access to theserverASP.Net
> application. And what is the configured Application Pool identity
> running the client ASP.Net application.
>
> FYI: This "hassle" is a good thing because it reminds the coders that
> they may not be as up-to-date on application security and
> authentication protocols as they should be. It is important to hassle
> coders to get it right because this is the front door and roadmap to
> theirserver'skingdom, and you want it to be sturdy and secure, not
> just gaping wide open. Security does not happen "automagically" - it
> happens by design.
>
> Personally, I think that if you get a 401, you should think "darn,
> what else did I forget" and NOT "darn, why is Microsoft making it a
> hassle". The era of running as administrator or LocalSystem to avoid
> "access denied" and have things "magically work" is over.
>
> //Davidhttp://w3-4u.blogspot.comhttp://blogs.msdn.com/David. Wang
> //
>
> On Mar 20, 11:08 am, Grant_S wrote:
>
>
>
> > I have an asp.net web application which posts a request to another asp.net web application. I am coding in C# using Visual studio 2003, with .Net Framework 1.1 on a Wiondows 2003server(running IIS 6.0.). In order to have all code running as managed code, I changed existing code which uses MSXML ServerXMLHTTPClass to post requests to code using the .Net HTTPWebRequest class. When migrating the application to the Test webserver, IIS appears to prevent access (=no record of the request in the Windows\System32\Logfiles\W3SVC1 files). I am using impersonation in the web.config file of the client and 'server' web applications. The Application needs to be configured in IIS to 'Windows Authentication' only. The impersonated account is a member of IIS_WPG group an has NTFS permissions to the Applications physical folder. Even if I open up security (allow everyone). There is no web proxy issue. Both client andServerapplications are at this point both on the same Testserverwith the same specs as the development machine (above).
>
> > THE ONLY WAY IT FUNCTIONS IS IF IIS FOR THE APPLICATION ON THESERVERHAS 'ENABLE ANONYMOUS' TICKED.
>
> > I see a lot of posts on the internet highlighting this problem without any difinitive answer. Surely, Microsoft wishes the Managed classes to be used. Why then does there appear to be such a hassle for coders to use the class to achieve the same result as the MSXML classes?
>
> > The code below is what I am using to make the call. Tracing shows that the callfailswhen the request is made (GetResponse()).
>
> > HttpWebRequest request=null;
> > Uri uri = new Uri(requestTargetAndQuery);
> > request = (HttpWebRequest) WebRequest.Create(uri);
> > request.Method = "GET";
> > request.Credentials = new NetworkCredential(this.m_User, this.m_Password);
> > string result=string.Empty;
> > using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
> > {
> > request response.",traceSwitch);
> > using (Stream responseStream = response.GetResponseStream())
> > {
> > using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8))
> > { result = readStream.ReadToEnd();
> > }
>
> > }
> > }
>
> > Hopefully someone can point me in the right direction (or let me know if the Framework class does not have the capability to achieve what I am trying)
>
> > Thanks Grant_S
>
> > Fromhttp://developmentnow.com/g/91_0_0_0_0_0/inetserver-iis- security.htm
>
> > Posted via DevelopmentNow.com Groupshttp://www.developmentnow.com- Hide quoted text -
>
> - Show quoted text -
David
Thanks for your reply. Point certainly taken regarding 'darn - what am
I missing'. Thus the frustration of not beating this yet. I really
need my Server web application to have IIS set to 'Windows
authentication' only before I am happy. You indicated that I have
conflicting settings. So that is a great start for me - as I am
unaware of this. I will try and clarify more what I am trying to
achieve.
I have two 'Client' Web applications, each which make calls to a
single 'Server' Web application. In the 'Test' environment, all
applications reside on the same server. In 'Production' the two
clients will be installed on a Server outside the firewall. So there
will no doubt be some proxy issues to overcome at when we migrate to
production. The stick point for me now is that everything works fine
when the 'Server' application IIS security is set to 'Enable
anonymous' but fails if is only set to 'Windows authentication'. More
detail of the settings below:
Client Application 1 - uses Windows Forms login. IIS for this
application is set to Windows Authentication only. The web.config for
the application is set to allow the users who successfully login and
deny all others (*); and also deny unauthenticated (?) as below:
[I imagine that the latter two above 'deny' are redundant - but have
left them for testing my scenario.]
Client Application 2 - has no GUI. The application is called by an
external application. IIS for this application uses only IP address
restriction and is set to 'Enable anonymous'
I have set the authorization section of the web.config file to:
[Again - this is probably what you refer to as redundant, given that
'Enable anonymous' is ticked in IIS security]
My intention is to impersonate ASP.Net - using a domain account.
Impersonation is achieved in the Client applications by using the
tag in the web.config file. The account used for
impersonation is a member of the local IIS_WPG group and also has
full control NTFS permissions on the physical folder and subfolders of
the web application. My understanding is that with these settings,
local resources required by these Web applications will need
permissions granted for the impersonated user (where they are not
already provided to IIS_WPG group).
When these applications make calls to the 'Server' Application, I am
setting the credentials for the call - using values which are stored
in a configuration file (for now these are the same as the
impersonated account). The Credentials are set in the client using:
request.Credentials = new NetworkCredential(this.m_User,
this.m_Password);
Server Application - If IIS for the application, is set with only
'Windows Authentication' ticked. Calls fail with the error 401. This
occurs when the authorization section in the web.config file is set to
allow (*) - so there is no restriction here. This application also
uses impersonation in the web.config file but the account used is a
local account.
You were correct about the log flushing. I do see results in the
LogFiles. Below is what I am seeing (altered for security):
2007-03-21 10:12:58 127.0.0.1 POST /MYWEBCLIENTAPP/MyWebPage.aspx - 80
- 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT
+5.2;+SV1;+.NET+CLR+1.1.4322) 401 1 0
2007-03-21 10:12:58 192.162.3.82 GET /MYSERVERWEBAPP/
MYSERVERWEBPAGE.aspx MYQUERYSTRINGPARAMETERS- 192.162.3.82 - 401 2
2148074254
2007-03-21 10:12:58 192.162.3.82 GET /MYSERVERWEBAPP/
MYSERVERWEBPAGE.aspx MYQUERYSTRINGPARAMETERS- 192.162.3.82 - 401 1 0
2007-03-21 10:12:58 192.162.3.82 GET /MYSERVERWEBAPP/
MYSERVERWEBPAGE.aspx MYQUERYSTRINGPARAMETERS- 192.162.3.82 - 401 1
2148074252
2007-03-21 10:12:58 127.0.0.1 POST /MYWEBCLIENTAPP/MyWebPage.aspx - 80
MYDOMAIN\Administrator 127.0.0.1 Mozilla/4.0+(compatible;+MSIE
+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322) 200 0 0
2007-03-21 10:12:58 127.0.0.1 GET /MYWEBCLIENTAPP/Styles.css - 80
MYDOMAIN\Administrator 127.0.0.1 Mozilla/4.0+(compatible;+MSIE
+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322) 301 0 0
2007-03-21 10:12:58 127.0.0.1 GET /MYWEBCLIENTAPP/Styles.css/ - 80
MYDOMAIN\Administrator 127.0.0.1 Mozilla/4.0+(compatible;+MSIE
+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322) 403 14 5
David, hopefully this clarifies what I am attempting to achieve.
Cheers
Grant